// ----------------------------------------------------------------------------- // IOidcTokenProvider.cs // Sprint: SPRINT_20251226_001_SIGNER_fulcio_keyless_client // Task: 0012 - Add OIDC token acquisition from Authority // Description: Interface for obtaining OIDC tokens for Fulcio authentication // ----------------------------------------------------------------------------- namespace StellaOps.Signer.Keyless; /// /// Provides OIDC identity tokens for Fulcio authentication. /// public interface IOidcTokenProvider { /// /// Gets the OIDC issuer URL. /// string Issuer { get; } /// /// Acquires an OIDC identity token. /// /// Cancellation token. /// The OIDC token result containing the identity token. Task AcquireTokenAsync(CancellationToken cancellationToken = default); /// /// Gets a cached token if available and not expired. /// /// The cached token, or null if not available or expired. OidcTokenResult? GetCachedToken(); /// /// Clears any cached tokens. /// void ClearCache(); } /// /// Result of OIDC token acquisition. /// public sealed record OidcTokenResult { /// /// The identity token (JWT). /// public required string IdentityToken { get; init; } /// /// When the token expires. /// public required DateTimeOffset ExpiresAt { get; init; } /// /// The subject claim from the token. /// public string? Subject { get; init; } /// /// The email claim from the token, if present. /// public string? Email { get; init; } /// /// Whether the token is expired. /// public bool IsExpired => DateTimeOffset.UtcNow >= ExpiresAt; /// /// Whether the token will expire within the specified buffer time. /// public bool WillExpireSoon(TimeSpan buffer) => DateTimeOffset.UtcNow.Add(buffer) >= ExpiresAt; } /// /// Configuration for client credentials OIDC flow. /// public sealed record OidcClientCredentialsConfig { /// /// The OIDC issuer URL. /// public required string Issuer { get; init; } /// /// The client ID. /// public required string ClientId { get; init; } /// /// The client secret. /// public required string ClientSecret { get; init; } /// /// Additional scopes to request. /// public IReadOnlyList Scopes { get; init; } = ["openid", "email"]; /// /// Token endpoint URL (if different from discovery). /// public string? TokenEndpoint { get; init; } } /// /// Configuration for ambient token OIDC (CI runner tokens, workload identity). /// public sealed record OidcAmbientConfig { /// /// The OIDC issuer URL. /// public required string Issuer { get; init; } /// /// Path to the ambient token file. /// public required string TokenPath { get; init; } /// /// Whether to watch the token file for changes. /// public bool WatchForChanges { get; init; } = true; }