Connection with managed identity to postgresql and token expiration
Vasile
0
Reputation points
Hello community, I have a Nest.Js app with TypeORM and PostgreSQL.I want to deploy my app to the azure and to connect the azure PostgreSQL database.I implemented next connection:
Database module:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { join } from 'path';
import { NODE_ENV } from 'src/common/enums/node.env.enum';
import { IPostgresConfig } from 'src/common/interfaces/postgres.config.interface';
import { getManagedIdentityCredential } from 'src/common/managed-identity/credential';
import { getDatabaseAccessToken } from 'src/common/managed-identity/database.access.token';
import { DataSource } from 'typeorm';
@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
const databaseConfig =
configService.get<IPostgresConfig>('postgresConfig');
const managedIdentityConfig = configService.get('managedIdentity');
const env = configService.get<string>('NODE_ENV');
const isTestEnv = env === NODE_ENV.TEST;
const _logging =
env !== NODE_ENV.LOCAL &&
env !== NODE_ENV.DEVELOPMENT &&
env !== NODE_ENV.TEST;
const _synchronize =
env === NODE_ENV.LOCAL ||
env === NODE_ENV.DEVELOPMENT ||
env === NODE_ENV.TEST;
const useSsl =
env === NODE_ENV.DEVELOPMENT ||
env === NODE_ENV.TEST ||
env === NODE_ENV.PRODUCTION;
const useManagedIdentity =
env === NODE_ENV.DEVELOPMENT ||
env === NODE_ENV.TEST ||
env === NODE_ENV.PRODUCTION;
let password: string;
if (useManagedIdentity) {
const credential = getManagedIdentityCredential(
managedIdentityConfig,
);
const accessToken = await getDatabaseAccessToken(credential);
password = accessToken.token;
} else {
password = databaseConfig.password;
}
return {
type: 'postgres',
host: databaseConfig.host,
database: isTestEnv ? 'test_db' : databaseConfig.database,
schema: databaseConfig.schema,
username: databaseConfig.user,
password,
port: +databaseConfig.port,
ssl: useSsl || { rejectUnauthorized: false },
entities: [
join(
__dirname,
'..',
'..',
'modules',
'**',
'entities',
'*.entity.{ts,js}',
),
join(
__dirname,
'..',
'..',
'common',
'entities',
'*.entity.{ts,js}',
),
join(__dirname, '..', '**', 'entities', '*.entity.{ts,js}'),
],
migrations: [join(__dirname, 'migrations', '*.{ts,js}')],
synchronize: _synchronize,
logging: _logging,
dropSchema: isTestEnv,
};
},
dataSourceFactory: async (options) => {
const dataSource = await new DataSource(options).initialize();
return dataSource;
},
}),
],
})
export class DatabaseModule {}
Credentials.ts
import { DefaultAzureCredential } from '@azure/identity';
type ManagedIdentityConfig = {
clientId: string;
};
export function getManagedIdentityCredential({
clientId,
}: ManagedIdentityConfig) {
const credential = new DefaultAzureCredential({
managedIdentityClientId: clientId,
});
return credential;
}
And database.access.token.ts
import { AccessToken, DefaultAzureCredential } from '@azure/identity';
const databaseScope = 'https://ossrdbms-aad.database.windows.net/.default';
export const getDatabaseAccessToken = async (
credential: DefaultAzureCredential,
): Promise<AccessToken> => {
const tokenResponse = await credential.getToken(databaseScope);
return tokenResponse;
};
The problem is that access token expires and the db connection get lost.And i get this error:
Maybe i do something wrong about managed identity?I have asked on Nestjs and TypeORM platforms but no answer.Thanks a lot already :)
Sign in to answer