AWS STS integration for NestJS applications.
npm install @onivoro/server-aws-stsAWS STS integration for NestJS applications.
``bash`
npm install @onivoro/server-aws-sts
This library provides a minimal AWS STS (Security Token Service) integration for NestJS applications, offering account ID retrieval functionality.
`typescript
import { Module } from '@nestjs/common';
import { ServerAwsStsModule } from '@onivoro/server-aws-sts';
@Module({
imports: [
ServerAwsStsModule.configure()
]
})
export class AppModule {}
`
The module uses environment-based configuration:
`typescript`
export class ServerAwsStsConfig {
AWS_REGION: string;
AWS_PROFILE?: string; // Optional AWS profile
}
The service provides a single method for retrieving the AWS account ID:
`typescript
import { Injectable } from '@nestjs/common';
import { StsService } from '@onivoro/server-aws-sts';
@Injectable()
export class AccountService {
constructor(private readonly stsService: StsService) {}
async getCurrentAccountId() {
const accountId = await this.stsService.getAccountId();
console.log(Current AWS Account: ${accountId});`
return accountId;
}
}
- getAccountId() - Retrieves the AWS account ID for the current credentials
The service exposes the underlying STS client for advanced operations:
`typescript
import { Injectable } from '@nestjs/common';
import { StsService } from '@onivoro/server-aws-sts';
import {
AssumeRoleCommand,
GetSessionTokenCommand,
GetAccessKeyInfoCommand
} from '@aws-sdk/client-sts';
@Injectable()
export class AdvancedStsService {
constructor(private readonly stsService: StsService) {}
// Assume a role
async assumeRole(roleArn: string, sessionName: string) {
const command = new AssumeRoleCommand({
RoleArn: roleArn,
RoleSessionName: sessionName,
DurationSeconds: 3600 // 1 hour
});
const response = await this.stsService.stsClient.send(command);
return response.Credentials;
}
// Get temporary session token
async getSessionToken(durationSeconds: number = 3600) {
const command = new GetSessionTokenCommand({
DurationSeconds: durationSeconds
});
const response = await this.stsService.stsClient.send(command);
return response.Credentials;
}
// Get access key info
async getAccessKeyInfo(accessKeyId: string) {
const command = new GetAccessKeyInfoCommand({
AccessKeyId: accessKeyId
});
return await this.stsService.stsClient.send(command);
}
// Get caller identity (alternative to getAccountId)
async getCallerIdentity() {
const command = new GetCallerIdentityCommand({});
const response = await this.stsService.stsClient.send(command);
return {
accountId: response.Account,
arn: response.Arn,
userId: response.UserId
};
}
}
`
`typescript
import { Module, Injectable, Controller, Get, Post, Body } from '@nestjs/common';
import { ServerAwsStsModule, StsService } from '@onivoro/server-aws-sts';
import { AssumeRoleCommand } from '@aws-sdk/client-sts';
@Module({
imports: [ServerAwsStsModule.configure()],
controllers: [SecurityController],
providers: [SecurityService]
})
export class SecurityModule {}
@Injectable()
export class SecurityService {
constructor(private readonly stsService: StsService) {}
async getCrossAccountCredentials(targetAccountId: string, roleName: string) {
const currentAccountId = await this.stsService.getAccountId();
const roleArn = arn:aws:iam::${targetAccountId}:role/${roleName};cross-account-${currentAccountId}-${Date.now()}
const sessionName = ;
const command = new AssumeRoleCommand({
RoleArn: roleArn,
RoleSessionName: sessionName,
DurationSeconds: 3600,
ExternalId: process.env.EXTERNAL_ID // If required by trust policy
});
try {
const response = await this.stsService.stsClient.send(command);
return {
accessKeyId: response.Credentials.AccessKeyId,
secretAccessKey: response.Credentials.SecretAccessKey,
sessionToken: response.Credentials.SessionToken,
expiration: response.Credentials.Expiration
};
} catch (error) {
console.error('Failed to assume role:', error);
throw error;
}
}
async validateCurrentCredentials() {
try {
const accountId = await this.stsService.getAccountId();
return {
valid: true,
accountId
};
} catch (error) {
return {
valid: false,
error: error.message
};
}
}
}
@Controller('security')
export class SecurityController {
constructor(private readonly securityService: SecurityService) {}
@Get('account')
async getAccountInfo() {
const accountId = await this.securityService.stsService.getAccountId();
return { accountId };
}
@Get('validate')
async validateCredentials() {
return await this.securityService.validateCurrentCredentials();
}
@Post('assume-role')
async assumeRole(@Body() body: {
targetAccountId: string;
roleName: string;
}) {
return await this.securityService.getCrossAccountCredentials(
body.targetAccountId,
body.roleName
);
}
}
`
`bashRequired
AWS_REGION=us-east-1
Common Use Cases
$3
`typescript
const accountId = await stsService.getAccountId();
if (accountId !== expectedAccountId) {
throw new Error('Running in wrong AWS account');
}
`$3
`typescript
const accountId = await stsService.getAccountId();
const bucketArn = arn:aws:s3:::my-bucket-${accountId};
`$3
`typescript
// Use the exposed stsClient for assume role operations
const assumeRoleCommand = new AssumeRoleCommand({
RoleArn: arn:aws:iam::${targetAccount}:role/${roleName},
RoleSessionName: 'my-session'
});
const credentials = await stsService.stsClient.send(assumeRoleCommand);
`Limitations
- Only provides
getAccountId() method out of the box
- No built-in support for role assumption or session tokens
- No credential caching or management
- For advanced STS operations, use the exposed stsClient directlyBest Practices
1. Credential Validation: Use
getAccountId()` to verify you're in the correct AWS accountMIT