feat(phase-3): workstream 3 — OpenID Connect (OIDC) Provider
Implements full OIDC layer on top of the existing OAuth 2.0 token service: - Migration 014: oidc_keys table (RSA/EC key pairs, is_current flag, expires_at for rotation grace period) - OIDCKeyService: key generation (RS256/ES256), Vault storage, JWKS with Redis cache, key rotation with grace period, pruneExpiredKeys - IDTokenService: buildIDTokenClaims (agent claims, nonce, DID), signIDToken (kid in JWT header), verifyIDToken (alg:none rejected, RS256/ES256 only) - OIDCController: discovery document, JWKS (Cache-Control), /agent-info - OIDC routes mounted at / — /.well-known/openid-configuration, /.well-known/jwks.json, /agent-info - OAuth2Service: id_token appended to token response when openid scope requested - 473 unit tests passing (100% OIDCKeyService stmts, 95.91% IDTokenService stmts) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,11 @@ export interface ITokenResponse {
|
||||
token_type: 'Bearer';
|
||||
expires_in: number;
|
||||
scope: string;
|
||||
/**
|
||||
* OIDC ID token — included when the `openid` scope is requested.
|
||||
* Signed RS256 or ES256 JWT containing agent identity claims.
|
||||
*/
|
||||
id_token?: string;
|
||||
}
|
||||
|
||||
/** OAuth 2.0 error response (RFC 6749 §5.2). */
|
||||
|
||||
152
src/types/oidc.ts
Normal file
152
src/types/oidc.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* OIDC type definitions for SentryAgent.ai AgentIdP.
|
||||
* Covers ID token claims, JWKS response, discovery document, and agent-info response.
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// JWKS Key and Response
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* A single JSON Web Key as returned in the JWKS endpoint.
|
||||
* Supports both RSA (RS256) and EC P-256 (ES256) keys.
|
||||
*/
|
||||
export interface IJWKSKey {
|
||||
/** Key ID — matches the `kid` header in signed JWTs. */
|
||||
kid: string;
|
||||
/** Key type: "RSA" or "EC". */
|
||||
kty: string;
|
||||
/** Intended use: always "sig" for signing keys. */
|
||||
use: string;
|
||||
/** Algorithm: "RS256" or "ES256". */
|
||||
alg: string;
|
||||
/** RSA: Base64url-encoded modulus. */
|
||||
n?: string;
|
||||
/** RSA: Base64url-encoded public exponent. */
|
||||
e?: string;
|
||||
/** EC: Curve name, e.g. "P-256". */
|
||||
crv?: string;
|
||||
/** EC: Base64url-encoded x coordinate. */
|
||||
x?: string;
|
||||
/** EC: Base64url-encoded y coordinate. */
|
||||
y?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* JWKS (JSON Web Key Set) response returned by the `/.well-known/jwks.json` endpoint.
|
||||
*/
|
||||
export interface IJWKSResponse {
|
||||
/** Array of JSON Web Keys. Includes all non-expired keys (for rotation grace period). */
|
||||
keys: IJWKSKey[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OIDC Key record (database row)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Represents a row in the `oidc_keys` table.
|
||||
*/
|
||||
export interface IOIDCKey {
|
||||
/** UUID primary key. */
|
||||
id: string;
|
||||
/** Key identifier (e.g. "key-20260330-001"). Used as JWT `kid` header. */
|
||||
kid: string;
|
||||
/** Signing algorithm: "RS256" or "ES256". */
|
||||
algorithm: string;
|
||||
/** Public key in JWK format as stored in DB. */
|
||||
public_key_jwk: IJWKSKey;
|
||||
/** Vault KV2 path where the private key is stored, or "dev:no-vault" in dev mode. */
|
||||
vault_key_path: string;
|
||||
/** True if this is the active signing key. Only one key is current at a time. */
|
||||
is_current: boolean;
|
||||
/** Timestamp when this key was generated. */
|
||||
created_at: Date;
|
||||
/** Timestamp when all tokens signed with this key will have expired. */
|
||||
expires_at: Date;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ID Token Claims
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Claims payload of an OIDC ID token.
|
||||
* Conforms to OpenID Connect Core 1.0 §2 with additional agent-specific claims.
|
||||
*/
|
||||
export interface IIDTokenClaims {
|
||||
/** Issuer — the OIDC provider URL. */
|
||||
iss: string;
|
||||
/** Subject — the agent UUID. */
|
||||
sub: string;
|
||||
/** Audience — the client_id that requested the token. */
|
||||
aud: string;
|
||||
/** Issued-at time (Unix seconds). */
|
||||
iat: number;
|
||||
/** Expiry time (Unix seconds). */
|
||||
exp: number;
|
||||
/** Nonce — if provided in the original request, echoed here for replay protection. */
|
||||
nonce?: string;
|
||||
/** Functional classification of the agent. */
|
||||
agent_type: string;
|
||||
/** Target deployment environment of the agent. */
|
||||
deployment_env: string;
|
||||
/** Organization UUID the agent belongs to. */
|
||||
organization_id: string;
|
||||
/** W3C DID identifier for the agent, if one has been generated. */
|
||||
did?: string;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OIDC Discovery Document
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* OpenID Connect Discovery 1.0 document returned by `/.well-known/openid-configuration`.
|
||||
* All standard fields are included; `authorization_endpoint` is a stub (not implemented in Phase 3).
|
||||
*/
|
||||
export interface IOIDCDiscoveryDocument {
|
||||
/** OIDC Issuer URL. Must match the `iss` claim in ID tokens. */
|
||||
issuer: string;
|
||||
/** Authorization endpoint (stub — not implemented in Phase 3). */
|
||||
authorization_endpoint: string;
|
||||
/** Token endpoint for the client_credentials grant. */
|
||||
token_endpoint: string;
|
||||
/** JWKS endpoint for ID token verification public keys. */
|
||||
jwks_uri: string;
|
||||
/** Supported response types. */
|
||||
response_types_supported: string[];
|
||||
/** Supported subject types. */
|
||||
subject_types_supported: string[];
|
||||
/** Supported ID token signing algorithms. */
|
||||
id_token_signing_alg_values_supported: string[];
|
||||
/** Supported OAuth 2.0 scopes. */
|
||||
scopes_supported: string[];
|
||||
/** Claims that may appear in ID tokens or the agent-info response. */
|
||||
claims_supported: string[];
|
||||
/** Supported grant types. */
|
||||
grant_types_supported: string[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Agent Info Response
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Response body for the `GET /agent-info` endpoint.
|
||||
* Returns agent identity claims for the authenticated agent, similar to OIDC UserInfo.
|
||||
*/
|
||||
export interface IAgentInfoResponse {
|
||||
/** Agent UUID (subject). */
|
||||
sub: string;
|
||||
/** Functional classification of the agent. */
|
||||
agent_type: string;
|
||||
/** Target deployment environment of the agent. */
|
||||
deployment_env: string;
|
||||
/** Organization UUID the agent belongs to. */
|
||||
organization_id: string;
|
||||
/** W3C DID identifier, if one has been generated. */
|
||||
did?: string;
|
||||
/** The OAuth 2.0 scope associated with the Bearer token used to call this endpoint. */
|
||||
scope: string;
|
||||
}
|
||||
Reference in New Issue
Block a user