Files
git.stella-ops.org/src/Signer/__Libraries/StellaOps.Signer.Keyless/IOidcTokenProvider.cs
StellaOps Bot c8f3120174 Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
2025-12-26 15:17:15 +02:00

127 lines
3.5 KiB
C#

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