// Copyright © StellaOps. All rights reserved. // SPDX-License-Identifier: AGPL-3.0-or-later // Sprint: SPRINT_20260112_018_CRYPTO_key_escrow_shamir // Tasks: ESCROW-003, ESCROW-004 namespace StellaOps.Cryptography.KeyEscrow; /// /// Service for key escrow operations using Shamir's Secret Sharing. /// public interface IKeyEscrowService { /// /// Escrow a key by splitting it into shares and distributing to agents. /// /// Identifier for the key being escrowed. /// The key material to escrow. /// Escrow configuration options. /// Cancellation token. /// Result containing share IDs and metadata. Task EscrowKeyAsync( string keyId, byte[] keyMaterial, KeyEscrowOptions options, CancellationToken cancellationToken = default); /// /// Recover a key from escrow using collected shares. /// /// Recovery request with authorization details. /// Decrypted shares from custodians. /// Cancellation token. /// Result containing recovered key material. Task RecoverKeyAsync( KeyRecoveryRequest request, IReadOnlyList shares, CancellationToken cancellationToken = default); /// /// Get escrow status for a key. /// /// Key identifier. /// Cancellation token. /// Escrow status or null if not escrowed. Task GetEscrowStatusAsync( string keyId, CancellationToken cancellationToken = default); /// /// List all escrowed keys. /// /// Cancellation token. /// List of escrowed key summaries. Task> ListEscrowedKeysAsync( CancellationToken cancellationToken = default); /// /// Revoke escrow for a key (delete all shares). /// /// Key identifier. /// Reason for revocation. /// Cancellation token. /// True if revocation succeeded. Task RevokeEscrowAsync( string keyId, string reason, CancellationToken cancellationToken = default); /// /// Re-escrow a key with new shares (after recovery or rotation). /// Invalidates previous shares. /// /// Key identifier. /// Key material to re-escrow. /// New escrow options (or null to use previous). /// Cancellation token. /// Result containing new share IDs. Task ReEscrowKeyAsync( string keyId, byte[] keyMaterial, KeyEscrowOptions? options = null, CancellationToken cancellationToken = default); } /// /// Options for key escrow operations. /// public sealed record KeyEscrowOptions { /// /// Minimum shares required for recovery (M in M-of-N). /// public required int Threshold { get; init; } /// /// Total shares to create (N in M-of-N). /// public required int TotalShares { get; init; } /// /// Days until shares expire. /// public int ExpirationDays { get; init; } = 365; /// /// IDs of agents to distribute shares to. /// Must have at least TotalShares agents. /// public IReadOnlyList? AgentIds { get; init; } /// /// Whether to require dual-control ceremony for recovery. /// public bool RequireDualControl { get; init; } = true; /// /// Metadata to attach to the escrow record. /// public IReadOnlyDictionary? Metadata { get; init; } } /// /// Status of a key's escrow. /// public sealed record KeyEscrowStatus { /// /// Key identifier. /// public required string KeyId { get; init; } /// /// Whether the key is currently escrowed. /// public required bool IsEscrowed { get; init; } /// /// Threshold for recovery. /// public int Threshold { get; init; } /// /// Total shares created. /// public int TotalShares { get; init; } /// /// Number of shares still valid (not expired or revoked). /// public int ValidShares { get; init; } /// /// When the escrow was created. /// public DateTimeOffset? CreatedAt { get; init; } /// /// When shares expire. /// public DateTimeOffset? ExpiresAt { get; init; } /// /// Whether recovery is currently possible. /// public bool CanRecover => ValidShares >= Threshold; /// /// Custodians holding shares. /// public IReadOnlyList? CustodianIds { get; init; } } /// /// Summary of an escrowed key. /// public sealed record KeyEscrowSummary { /// /// Key identifier. /// public required string KeyId { get; init; } /// /// Threshold for recovery. /// public required int Threshold { get; init; } /// /// Total shares. /// public required int TotalShares { get; init; } /// /// When escrowed. /// public required DateTimeOffset CreatedAt { get; init; } /// /// When shares expire. /// public required DateTimeOffset ExpiresAt { get; init; } /// /// Escrow metadata. /// public IReadOnlyDictionary? Metadata { get; init; } }