feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+7
View File
@@ -0,0 +1,7 @@
import type { Provider } from "../internal/provider.mjs";
import { type BedrockBearerOptions, type BedrockEndpointOptions } from "../internal/bedrock.mjs";
export interface BedrockProviderOptions extends BedrockEndpointOptions, BedrockBearerOptions {
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer authentication. */
export declare function bedrock(options?: BedrockProviderOptions): Provider;
//# sourceMappingURL=bedrock.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bedrock.d.mts","sourceRoot":"","sources":["../src/providers/bedrock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,iCAA6B;AAErD,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,gCAA4B;AAE7B,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,oBAAoB;CAAG;AAE/F,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,OAAO,GAAE,sBAA2B,GAAG,QAAQ,CAmBtE"}
+7
View File
@@ -0,0 +1,7 @@
import type { Provider } from "../internal/provider.js";
import { type BedrockBearerOptions, type BedrockEndpointOptions } from "../internal/bedrock.js";
export interface BedrockProviderOptions extends BedrockEndpointOptions, BedrockBearerOptions {
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer authentication. */
export declare function bedrock(options?: BedrockProviderOptions): Provider;
//# sourceMappingURL=bedrock.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../src/providers/bedrock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,gCAA6B;AAErD,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,+BAA4B;AAE7B,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,oBAAoB;CAAG;AAE/F,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,OAAO,GAAE,sBAA2B,GAAG,QAAQ,CAmBtE"}
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bedrock = bedrock;
const tslib_1 = require("../internal/tslib.js");
const Errors = tslib_1.__importStar(require("../error.js"));
const provider_1 = require("../internal/provider.js");
const bedrock_1 = require("../internal/bedrock.js");
/** Configure the standard OpenAI client for Amazon Bedrock using bearer authentication. */
function bedrock(options = {}) {
const { baseURL } = (0, bedrock_1.resolveBedrockEndpoint)(options);
const { factory } = (0, bedrock_1.resolveBedrockBearerAuth)(options);
if (!factory) {
throw new Errors.OpenAIError('Bedrock bearer authentication requires an `apiKey`, `tokenProvider`, or `AWS_BEARER_TOKEN_BEDROCK`. For AWS credential authentication, import `bedrock` from `openai/providers/bedrock/aws`.');
}
return (0, provider_1.createProvider)({
configure() {
const auth = factory();
return {
name: 'bedrock',
baseURL,
prepareRequest: auth.prepareRequest.bind(auth),
};
},
});
}
//# sourceMappingURL=bedrock.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../src/providers/bedrock.ts"],"names":[],"mappings":";;AAaA,0BAmBC;;AAhCD,4DAAmC;AAEnC,sDAAsD;AACtD,oDAK6B;AAI7B,2FAA2F;AAC3F,SAAgB,OAAO,CAAC,UAAkC,EAAE;IAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;IACpD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,kCAAwB,EAAC,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,MAAM,CAAC,WAAW,CAC1B,8LAA8L,CAC/L,CAAC;IACJ,CAAC;IAED,OAAO,IAAA,yBAAc,EAAC;QACpB,SAAS;YACP,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;YACvB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO;gBACP,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;aAC/C,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
+22
View File
@@ -0,0 +1,22 @@
import * as Errors from "../error.mjs";
import { createProvider } from "../internal/provider.mjs";
import { resolveBedrockBearerAuth, resolveBedrockEndpoint, } from "../internal/bedrock.mjs";
/** Configure the standard OpenAI client for Amazon Bedrock using bearer authentication. */
export function bedrock(options = {}) {
const { baseURL } = resolveBedrockEndpoint(options);
const { factory } = resolveBedrockBearerAuth(options);
if (!factory) {
throw new Errors.OpenAIError('Bedrock bearer authentication requires an `apiKey`, `tokenProvider`, or `AWS_BEARER_TOKEN_BEDROCK`. For AWS credential authentication, import `bedrock` from `openai/providers/bedrock/aws`.');
}
return createProvider({
configure() {
const auth = factory();
return {
name: 'bedrock',
baseURL,
prepareRequest: auth.prepareRequest.bind(auth),
};
},
});
}
//# sourceMappingURL=bedrock.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bedrock.mjs","sourceRoot":"","sources":["../src/providers/bedrock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAiB;AAEnC,OAAO,EAAE,cAAc,EAAE,iCAA6B;AACtD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GAGvB,gCAA4B;AAI7B,2FAA2F;AAC3F,MAAM,UAAU,OAAO,CAAC,UAAkC,EAAE;IAC1D,MAAM,EAAE,OAAO,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,EAAE,OAAO,EAAE,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,MAAM,CAAC,WAAW,CAC1B,8LAA8L,CAC/L,CAAC;IACJ,CAAC;IAED,OAAO,cAAc,CAAC;QACpB,SAAS;YACP,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;YACvB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO;gBACP,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;aAC/C,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
+24
View File
@@ -0,0 +1,24 @@
import { type BedrockBearerOptions, type BedrockEndpointOptions } from "../../internal/bedrock.mjs";
import { type Provider } from "../../internal/provider.mjs";
export interface AwsCredentialIdentity {
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
expiration?: Date;
}
export type AwsCredentialsProvider = () => AwsCredentialIdentity | Promise<AwsCredentialIdentity>;
export interface BedrockProviderOptions extends BedrockEndpointOptions, BedrockBearerOptions {
/** Explicit AWS access key ID. Must be paired with secretAccessKey. */
accessKeyId?: string | undefined;
/** Explicit AWS secret access key. Must be paired with accessKeyId. */
secretAccessKey?: string | undefined;
/** Optional session token for explicit temporary AWS credentials. */
sessionToken?: string | undefined;
/** Explicit AWS shared-config profile. */
profile?: string | undefined;
/** A refreshable provider returning AWS credentials. */
credentialProvider?: AwsCredentialsProvider | undefined;
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer or AWS authentication. */
export declare function bedrock(options?: BedrockProviderOptions): Provider;
//# sourceMappingURL=aws.d.mts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"aws.d.mts","sourceRoot":"","sources":["../../src/providers/bedrock/aws.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAE5B,mCAA+B;AAChC,OAAO,EAAkB,KAAK,QAAQ,EAA+B,oCAAgC;AAKrG,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAElG,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,oBAAoB;IAC1F,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAElC,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;CACzD;AAiKD,kGAAkG;AAClG,wBAAgB,OAAO,CAAC,OAAO,GAAE,sBAA2B,GAAG,QAAQ,CA+CtE"}
+24
View File
@@ -0,0 +1,24 @@
import { type BedrockBearerOptions, type BedrockEndpointOptions } from "../../internal/bedrock.js";
import { type Provider } from "../../internal/provider.js";
export interface AwsCredentialIdentity {
accessKeyId: string;
secretAccessKey: string;
sessionToken?: string;
expiration?: Date;
}
export type AwsCredentialsProvider = () => AwsCredentialIdentity | Promise<AwsCredentialIdentity>;
export interface BedrockProviderOptions extends BedrockEndpointOptions, BedrockBearerOptions {
/** Explicit AWS access key ID. Must be paired with secretAccessKey. */
accessKeyId?: string | undefined;
/** Explicit AWS secret access key. Must be paired with accessKeyId. */
secretAccessKey?: string | undefined;
/** Optional session token for explicit temporary AWS credentials. */
sessionToken?: string | undefined;
/** Explicit AWS shared-config profile. */
profile?: string | undefined;
/** A refreshable provider returning AWS credentials. */
credentialProvider?: AwsCredentialsProvider | undefined;
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer or AWS authentication. */
export declare function bedrock(options?: BedrockProviderOptions): Provider;
//# sourceMappingURL=aws.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../../src/providers/bedrock/aws.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAE5B,kCAA+B;AAChC,OAAO,EAAkB,KAAK,QAAQ,EAA+B,mCAAgC;AAKrG,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAElG,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,oBAAoB;IAC1F,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAElC,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;CACzD;AAiKD,kGAAkG;AAClG,wBAAgB,OAAO,CAAC,OAAO,GAAE,sBAA2B,GAAG,QAAQ,CA+CtE"}
+170
View File
@@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bedrock = bedrock;
const tslib_1 = require("../../internal/tslib.js");
const credential_provider_node_1 = require("@aws-sdk/credential-provider-node");
const hash_node_1 = require("@smithy/hash-node");
const signature_v4_1 = require("@smithy/signature-v4");
const Errors = tslib_1.__importStar(require("../../error.js"));
const bedrock_1 = require("../../internal/bedrock.js");
const provider_1 = require("../../internal/provider.js");
const BEDROCK_SERVICE = 'bedrock-mantle';
function validateStaticCredentials(options) {
const hasAccessKey = options.accessKeyId !== undefined;
const hasSecretKey = options.secretAccessKey !== undefined;
if (hasAccessKey !== hasSecretKey || (options.sessionToken !== undefined && !hasAccessKey)) {
throw new Errors.OpenAIError('The `accessKeyId` and `secretAccessKey` options must be provided together. A `sessionToken` may only be used with both.');
}
if (!hasAccessKey)
return undefined;
if (typeof options.accessKeyId !== 'string' ||
!options.accessKeyId.trim() ||
typeof options.secretAccessKey !== 'string' ||
!options.secretAccessKey.trim()) {
throw new Errors.OpenAIError('Static AWS credentials require non-empty `accessKeyId` and `secretAccessKey` values.');
}
if (options.sessionToken !== undefined &&
(typeof options.sessionToken !== 'string' || !options.sessionToken.trim())) {
throw new Errors.OpenAIError('A static AWS `sessionToken` must not be empty when provided.');
}
return {
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
...(options.sessionToken ? { sessionToken: options.sessionToken } : {}),
};
}
function requestTarget(parsedURL) {
const query = {};
for (const [name, value] of parsedURL.searchParams) {
const existing = query[name];
query[name] =
existing === undefined ? value
: typeof existing === 'string' ? [existing, value]
: [...existing, value];
}
return { path: parsedURL.pathname, query };
}
function signableBody(body) {
if (body === undefined || body === null)
return undefined;
if (typeof body === 'string' || body instanceof ArrayBuffer || ArrayBuffer.isView(body))
return body;
throw new Errors.OpenAIError("The SDK's Bedrock SigV4 mode requires a replayable request body. Buffer the body before sending or use bearer authentication.");
}
function validateCredentialIdentity(identity) {
if (typeof identity?.accessKeyId !== 'string' ||
!identity.accessKeyId.trim() ||
typeof identity.secretAccessKey !== 'string' ||
!identity.secretAccessKey.trim() ||
(identity.sessionToken !== undefined &&
(typeof identity.sessionToken !== 'string' || !identity.sessionToken.trim()))) {
throw new Errors.OpenAIError('Failed to resolve AWS credentials for Bedrock. Verify your AWS profile, environment variables, or runtime identity configuration and try again.');
}
return identity;
}
class BedrockSigV4Auth {
constructor(options) {
this.options = options;
}
credentialsProvider() {
if (this.resolvedCredentialsProvider)
return this.resolvedCredentialsProvider;
if (this.options.staticCredentials) {
const credentials = this.options.staticCredentials;
return (this.resolvedCredentialsProvider = async () => credentials);
}
if (this.options.credentialProvider) {
const provider = this.options.credentialProvider;
return (this.resolvedCredentialsProvider = async () => validateCredentialIdentity(await provider()));
}
const provider = (0, credential_provider_node_1.defaultProvider)(this.options.profile ? { profile: this.options.profile } : {});
return (this.resolvedCredentialsProvider = async () => validateCredentialIdentity(await provider()));
}
signatureV4() {
return (this.signer ?? (this.signer = new signature_v4_1.SignatureV4({
credentials: this.credentialsProvider(),
region: this.options.region,
service: BEDROCK_SERVICE,
sha256: hash_node_1.Hash.bind(null, 'sha256'),
})));
}
async prepareRequest(request, { url }) {
if (Object.prototype.toString.call(globalThis.process) !== '[object process]') {
throw new Errors.OpenAIError('Bedrock AWS credential authentication is only supported in Node.js and compatible server runtimes. Use bearer authentication in this runtime.');
}
const parsedURL = new URL(url);
const canonicalRegion = /^bedrock-mantle\.([a-z0-9-]+)\.api\.aws$/i.exec(parsedURL.hostname)?.[1];
if (canonicalRegion && canonicalRegion !== this.options.region) {
throw new Errors.OpenAIError(`The Bedrock endpoint region \`${canonicalRegion}\` does not match the SigV4 region \`${this.options.region}\`.`);
}
const headers = new Headers(request.headers);
(0, bedrock_1.assertProviderOwnsAuthorization)(headers);
headers.delete('x-amz-date');
headers.delete('x-amz-security-token');
headers.delete('x-amz-content-sha256');
headers.set('host', parsedURL.host);
const method = (request.method ?? 'GET').toUpperCase();
const body = signableBody(request.body);
let signed;
try {
signed = await this.signatureV4().sign({
protocol: parsedURL.protocol,
hostname: parsedURL.hostname,
...(parsedURL.port ? { port: Number(parsedURL.port) } : {}),
method,
...requestTarget(parsedURL),
headers: Object.fromEntries(headers.entries()),
...(body !== undefined ? { body } : {}),
});
}
catch (cause) {
const message = this.options.usesDefaultChain ?
'Could not find credentials for Bedrock. Pass AWS credentials to `bedrock(...)` or configure the default AWS credential chain.'
: 'Failed to resolve AWS credentials for Bedrock. Verify your AWS profile, environment variables, or runtime identity configuration and try again.';
throw (0, bedrock_1.errorWithCause)(message, cause);
}
request.method = method;
request.redirect = 'manual';
request.headers = new Headers(signed.headers);
}
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer or AWS authentication. */
function bedrock(options = {}) {
const staticCredentials = validateStaticCredentials(options);
const profile = (0, bedrock_1.normalizeOptionalString)(options.profile);
if (options.profile !== undefined && !profile) {
throw new Errors.OpenAIError('The Bedrock AWS `profile` must not be empty.');
}
const awsModes = [!!staticCredentials, !!profile, !!options.credentialProvider].filter(Boolean).length;
if (awsModes > 1) {
throw new Errors.OpenAIError('Bedrock authentication is ambiguous. Configure exactly one explicit AWS mode: static credentials, profile, or credential provider.');
}
const explicitAwsAuth = awsModes === 1;
const bearerAuth = (0, bedrock_1.resolveBedrockBearerAuth)(options, { allowEnvironment: !explicitAwsAuth });
if (bearerAuth.explicit && explicitAwsAuth) {
throw new Errors.OpenAIError('Bearer and AWS credential authentication are mutually exclusive. Configure exactly one explicit mode: bearer credential, static AWS credentials, profile, or credential provider.');
}
const { region, baseURL } = (0, bedrock_1.resolveBedrockEndpoint)(options);
if (!bearerAuth.factory && !region) {
throw new Errors.OpenAIError('Bedrock requires an AWS region. Pass `region` to `bedrock(...)`, or set `AWS_REGION` or `AWS_DEFAULT_REGION`.');
}
const credentialProvider = options.credentialProvider;
return (0, provider_1.createProvider)({
configure() {
const auth = bearerAuth.factory?.() ??
new BedrockSigV4Auth({
region: region,
staticCredentials,
profile,
credentialProvider,
usesDefaultChain: !explicitAwsAuth,
});
return {
name: 'bedrock',
baseURL,
prepareRequest: auth.prepareRequest.bind(auth),
};
},
});
}
//# sourceMappingURL=aws.js.map
File diff suppressed because one or more lines are too long
+166
View File
@@ -0,0 +1,166 @@
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { Hash } from '@smithy/hash-node';
import { SignatureV4 } from '@smithy/signature-v4';
import * as Errors from "../../error.mjs";
import { assertProviderOwnsAuthorization, errorWithCause, normalizeOptionalString, resolveBedrockBearerAuth, resolveBedrockEndpoint, } from "../../internal/bedrock.mjs";
import { createProvider } from "../../internal/provider.mjs";
const BEDROCK_SERVICE = 'bedrock-mantle';
function validateStaticCredentials(options) {
const hasAccessKey = options.accessKeyId !== undefined;
const hasSecretKey = options.secretAccessKey !== undefined;
if (hasAccessKey !== hasSecretKey || (options.sessionToken !== undefined && !hasAccessKey)) {
throw new Errors.OpenAIError('The `accessKeyId` and `secretAccessKey` options must be provided together. A `sessionToken` may only be used with both.');
}
if (!hasAccessKey)
return undefined;
if (typeof options.accessKeyId !== 'string' ||
!options.accessKeyId.trim() ||
typeof options.secretAccessKey !== 'string' ||
!options.secretAccessKey.trim()) {
throw new Errors.OpenAIError('Static AWS credentials require non-empty `accessKeyId` and `secretAccessKey` values.');
}
if (options.sessionToken !== undefined &&
(typeof options.sessionToken !== 'string' || !options.sessionToken.trim())) {
throw new Errors.OpenAIError('A static AWS `sessionToken` must not be empty when provided.');
}
return {
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
...(options.sessionToken ? { sessionToken: options.sessionToken } : {}),
};
}
function requestTarget(parsedURL) {
const query = {};
for (const [name, value] of parsedURL.searchParams) {
const existing = query[name];
query[name] =
existing === undefined ? value
: typeof existing === 'string' ? [existing, value]
: [...existing, value];
}
return { path: parsedURL.pathname, query };
}
function signableBody(body) {
if (body === undefined || body === null)
return undefined;
if (typeof body === 'string' || body instanceof ArrayBuffer || ArrayBuffer.isView(body))
return body;
throw new Errors.OpenAIError("The SDK's Bedrock SigV4 mode requires a replayable request body. Buffer the body before sending or use bearer authentication.");
}
function validateCredentialIdentity(identity) {
if (typeof identity?.accessKeyId !== 'string' ||
!identity.accessKeyId.trim() ||
typeof identity.secretAccessKey !== 'string' ||
!identity.secretAccessKey.trim() ||
(identity.sessionToken !== undefined &&
(typeof identity.sessionToken !== 'string' || !identity.sessionToken.trim()))) {
throw new Errors.OpenAIError('Failed to resolve AWS credentials for Bedrock. Verify your AWS profile, environment variables, or runtime identity configuration and try again.');
}
return identity;
}
class BedrockSigV4Auth {
constructor(options) {
this.options = options;
}
credentialsProvider() {
if (this.resolvedCredentialsProvider)
return this.resolvedCredentialsProvider;
if (this.options.staticCredentials) {
const credentials = this.options.staticCredentials;
return (this.resolvedCredentialsProvider = async () => credentials);
}
if (this.options.credentialProvider) {
const provider = this.options.credentialProvider;
return (this.resolvedCredentialsProvider = async () => validateCredentialIdentity(await provider()));
}
const provider = defaultProvider(this.options.profile ? { profile: this.options.profile } : {});
return (this.resolvedCredentialsProvider = async () => validateCredentialIdentity(await provider()));
}
signatureV4() {
return (this.signer ?? (this.signer = new SignatureV4({
credentials: this.credentialsProvider(),
region: this.options.region,
service: BEDROCK_SERVICE,
sha256: Hash.bind(null, 'sha256'),
})));
}
async prepareRequest(request, { url }) {
if (Object.prototype.toString.call(globalThis.process) !== '[object process]') {
throw new Errors.OpenAIError('Bedrock AWS credential authentication is only supported in Node.js and compatible server runtimes. Use bearer authentication in this runtime.');
}
const parsedURL = new URL(url);
const canonicalRegion = /^bedrock-mantle\.([a-z0-9-]+)\.api\.aws$/i.exec(parsedURL.hostname)?.[1];
if (canonicalRegion && canonicalRegion !== this.options.region) {
throw new Errors.OpenAIError(`The Bedrock endpoint region \`${canonicalRegion}\` does not match the SigV4 region \`${this.options.region}\`.`);
}
const headers = new Headers(request.headers);
assertProviderOwnsAuthorization(headers);
headers.delete('x-amz-date');
headers.delete('x-amz-security-token');
headers.delete('x-amz-content-sha256');
headers.set('host', parsedURL.host);
const method = (request.method ?? 'GET').toUpperCase();
const body = signableBody(request.body);
let signed;
try {
signed = await this.signatureV4().sign({
protocol: parsedURL.protocol,
hostname: parsedURL.hostname,
...(parsedURL.port ? { port: Number(parsedURL.port) } : {}),
method,
...requestTarget(parsedURL),
headers: Object.fromEntries(headers.entries()),
...(body !== undefined ? { body } : {}),
});
}
catch (cause) {
const message = this.options.usesDefaultChain ?
'Could not find credentials for Bedrock. Pass AWS credentials to `bedrock(...)` or configure the default AWS credential chain.'
: 'Failed to resolve AWS credentials for Bedrock. Verify your AWS profile, environment variables, or runtime identity configuration and try again.';
throw errorWithCause(message, cause);
}
request.method = method;
request.redirect = 'manual';
request.headers = new Headers(signed.headers);
}
}
/** Configure the standard OpenAI client for Amazon Bedrock using bearer or AWS authentication. */
export function bedrock(options = {}) {
const staticCredentials = validateStaticCredentials(options);
const profile = normalizeOptionalString(options.profile);
if (options.profile !== undefined && !profile) {
throw new Errors.OpenAIError('The Bedrock AWS `profile` must not be empty.');
}
const awsModes = [!!staticCredentials, !!profile, !!options.credentialProvider].filter(Boolean).length;
if (awsModes > 1) {
throw new Errors.OpenAIError('Bedrock authentication is ambiguous. Configure exactly one explicit AWS mode: static credentials, profile, or credential provider.');
}
const explicitAwsAuth = awsModes === 1;
const bearerAuth = resolveBedrockBearerAuth(options, { allowEnvironment: !explicitAwsAuth });
if (bearerAuth.explicit && explicitAwsAuth) {
throw new Errors.OpenAIError('Bearer and AWS credential authentication are mutually exclusive. Configure exactly one explicit mode: bearer credential, static AWS credentials, profile, or credential provider.');
}
const { region, baseURL } = resolveBedrockEndpoint(options);
if (!bearerAuth.factory && !region) {
throw new Errors.OpenAIError('Bedrock requires an AWS region. Pass `region` to `bedrock(...)`, or set `AWS_REGION` or `AWS_DEFAULT_REGION`.');
}
const credentialProvider = options.credentialProvider;
return createProvider({
configure() {
const auth = bearerAuth.factory?.() ??
new BedrockSigV4Auth({
region: region,
staticCredentials,
profile,
credentialProvider,
usesDefaultChain: !explicitAwsAuth,
});
return {
name: 'bedrock',
baseURL,
prepareRequest: auth.prepareRequest.bind(auth),
};
},
});
}
//# sourceMappingURL=aws.mjs.map
File diff suppressed because one or more lines are too long