< Summary

Information
Class: AsiBackbone.Signing.ManagedKey.ManagedKeySigningServiceCollectionExtensions
Assembly: AsiBackbone.Signing.ManagedKey
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Signing.ManagedKey/ManagedKeySigningServiceCollectionExtensions.cs
Line coverage
100%
Covered lines: 69
Uncovered lines: 0
Coverable lines: 69
Total lines: 168
Line coverage: 100%
Branch coverage
91%
Covered branches: 11
Total branches: 12
Branch coverage: 91.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Signing.ManagedKey/ManagedKeySigningServiceCollectionExtensions.cs

#LineLine coverage
 1using AsiBackbone.Core.Signing;
 2using Microsoft.Extensions.DependencyInjection;
 3
 4namespace AsiBackbone.Signing.ManagedKey;
 5
 6/// <summary>
 7/// Provides dependency injection registration helpers for managed-key signing.
 8/// </summary>
 9public static class ManagedKeySigningServiceCollectionExtensions
 10{
 11    /// <summary>
 12    /// Adds production-oriented managed-key signing with a host-owned managed-key client factory.
 13    /// </summary>
 14    /// <remarks>
 15    /// The production-oriented registration fails closed by default because <see cref="ManagedKeySigningOptions.ReturnU
 16    /// defaults to <see langword="false" />.
 17    /// </remarks>
 18    public static IServiceCollection AddAsiBackboneManagedKeySigning(
 19        this IServiceCollection services,
 20        Action<ManagedKeySigningOptions> configure,
 21        Func<IServiceProvider, IManagedKeySigningClient> clientFactory)
 22    {
 623        ArgumentNullException.ThrowIfNull(services);
 524        ArgumentNullException.ThrowIfNull(configure);
 425        ArgumentNullException.ThrowIfNull(clientFactory);
 26
 327        ManagedKeySigningOptions options = new();
 328        configure(options);
 329        options.Validate();
 30
 331        return AddManagedKeySigningCore(services, options, clientFactory);
 32    }
 33
 34    /// <summary>
 35    /// Adds production-oriented managed-key signing using an already-registered <see cref="IManagedKeySigningClient" />
 36    /// </summary>
 37    /// <remarks>
 38    /// The production-oriented registration fails closed by default because <see cref="ManagedKeySigningOptions.ReturnU
 39    /// defaults to <see langword="false" />.
 40    /// </remarks>
 41    public static IServiceCollection AddAsiBackboneManagedKeySigning(
 42        this IServiceCollection services,
 43        Action<ManagedKeySigningOptions> configure)
 44    {
 945        ArgumentNullException.ThrowIfNull(services);
 846        ArgumentNullException.ThrowIfNull(configure);
 47
 748        ManagedKeySigningOptions options = new();
 749        configure(options);
 750        options.Validate();
 51
 652        return AddManagedKeySigningCore(services, options);
 53    }
 54
 55    /// <summary>
 56    /// Adds local-validation managed-key signing with a host-owned managed-key client factory.
 57    /// </summary>
 58    /// <remarks>
 59    /// This helper explicitly sets <see cref="ManagedKeySigningOptions.ReturnUnsignedOnFailure" /> to <see langword="tr
 60    /// so samples, tests, and diagnostics can inspect unsigned failure metadata. Do not use this helper as the default
 61    /// production registration unless host policy explicitly routes unsigned failure metadata.
 62    /// </remarks>
 63    public static IServiceCollection AddAsiBackboneManagedKeySigningForLocalValidation(
 64        this IServiceCollection services,
 65        Action<ManagedKeySigningOptions> configure,
 66        Func<IServiceProvider, IManagedKeySigningClient> clientFactory)
 67    {
 568        ArgumentNullException.ThrowIfNull(services);
 469        ArgumentNullException.ThrowIfNull(configure);
 370        ArgumentNullException.ThrowIfNull(clientFactory);
 71
 272        ManagedKeySigningOptions options = new();
 273        configure(options);
 274        options.ReturnUnsignedOnFailure = true;
 275        options.Validate();
 76
 277        return AddManagedKeySigningCore(services, options, clientFactory);
 78    }
 79
 80    /// <summary>
 81    /// Adds local-validation managed-key signing using an already-registered <see cref="IManagedKeySigningClient" />.
 82    /// </summary>
 83    /// <remarks>
 84    /// This helper explicitly sets <see cref="ManagedKeySigningOptions.ReturnUnsignedOnFailure" /> to <see langword="tr
 85    /// so samples, tests, and diagnostics can inspect unsigned failure metadata. Do not use this helper as the default
 86    /// production registration unless host policy explicitly routes unsigned failure metadata.
 87    /// </remarks>
 88    public static IServiceCollection AddAsiBackboneManagedKeySigningForLocalValidation(
 89        this IServiceCollection services,
 90        Action<ManagedKeySigningOptions> configure)
 91    {
 392        ArgumentNullException.ThrowIfNull(services);
 293        ArgumentNullException.ThrowIfNull(configure);
 94
 195        ManagedKeySigningOptions options = new();
 196        configure(options);
 197        options.ReturnUnsignedOnFailure = true;
 198        options.Validate();
 99
 1100        return AddManagedKeySigningCore(services, options);
 101    }
 102
 103    private static IServiceCollection AddManagedKeySigningCore(
 104        IServiceCollection services,
 105        ManagedKeySigningOptions options,
 106        Func<IServiceProvider, IManagedKeySigningClient> clientFactory)
 107    {
 5108        _ = services.AddSingleton(options);
 5109        _ = services.AddSingleton(clientFactory);
 5110        _ = services.AddSingleton(provider =>
 5111        {
 5112            ThrowIfProductionWithoutVerification(provider);
 5113            return new ManagedKeySigningService(
 5114                provider.GetRequiredService<ManagedKeySigningOptions>(),
 5115                provider.GetRequiredService<IManagedKeySigningClient>());
 5116        });
 5117        _ = services.AddSingleton<IGovernanceSigningService>(provider =>
 5118            provider.GetRequiredService<ManagedKeySigningService>());
 119
 5120        return services;
 121    }
 122
 123    private static IServiceCollection AddManagedKeySigningCore(
 124        IServiceCollection services,
 125        ManagedKeySigningOptions options)
 126    {
 7127        _ = services.AddSingleton(options);
 7128        _ = services.AddSingleton(provider =>
 7129        {
 7130            ThrowIfProductionWithoutVerification(provider);
 7131            return new ManagedKeySigningService(
 7132                provider.GetRequiredService<ManagedKeySigningOptions>(),
 7133                provider.GetRequiredService<IManagedKeySigningClient>());
 7134        });
 7135        _ = services.AddSingleton<IGovernanceSigningService>(provider =>
 7136            provider.GetRequiredService<ManagedKeySigningService>());
 137
 7138        return services;
 139    }
 140
 141    private static void ThrowIfProductionWithoutVerification(IServiceProvider serviceProvider)
 142    {
 12143        string? dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
 12144        string? aspNetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
 12145        bool hasExplicitEnvironment = !string.IsNullOrWhiteSpace(dotnetEnvironment)
 12146            || !string.IsNullOrWhiteSpace(aspNetCoreEnvironment);
 12147        bool isProduction = !hasExplicitEnvironment
 12148            || string.Equals(dotnetEnvironment, "Production", StringComparison.OrdinalIgnoreCase)
 12149            || string.Equals(aspNetCoreEnvironment, "Production", StringComparison.OrdinalIgnoreCase);
 150
 12151        if (!isProduction)
 152        {
 4153            return;
 154        }
 155
 8156        IServiceProviderIsService? isService = serviceProvider.GetService<IServiceProviderIsService>();
 8157        bool hasVerificationRegistration = isService?.IsService(typeof(IGovernanceSignatureVerificationService))
 8158            ?? (serviceProvider.GetService<IGovernanceSignatureVerificationService>() is not null);
 159
 8160        if (!hasVerificationRegistration)
 161        {
 3162            throw new InvalidOperationException(
 3163                "Managed-key signing is being resolved in Production without an IGovernanceSignatureVerificationService.
 3164                "This host signs artifacts but never verifies them, which silently breaks trust validation. " +
 3165                "Register a verification implementation before resolving the signing service or move this registration b
 166        }
 5167    }
 168}