| | | 1 | | using AsiBackbone.AspNetCore.Endpoints; |
| | | 2 | | using AsiBackbone.Core.Evaluation; |
| | | 3 | | using AsiBackbone.DependencyInjection; |
| | | 4 | | using Microsoft.Extensions.DependencyInjection; |
| | | 5 | | |
| | | 6 | | namespace AsiBackbone.AspNetCore.DependencyInjection; |
| | | 7 | | |
| | | 8 | | /// <summary> |
| | | 9 | | /// Provides strict governance registration helpers for hosts that prefer fail-closed defaults. |
| | | 10 | | /// </summary> |
| | | 11 | | public static class AsiBackboneStrictGovernanceServiceCollectionExtensions |
| | | 12 | | { |
| | | 13 | | /// <summary> |
| | | 14 | | /// Applies the strict governance profile for policy evaluation and ASP.NET Core endpoint governance options. |
| | | 15 | | /// </summary> |
| | | 16 | | /// <param name="services">The service collection to configure.</param> |
| | | 17 | | /// <returns>The same service collection so calls can be chained.</returns> |
| | | 18 | | /// <exception cref="ArgumentNullException"> |
| | | 19 | | /// Thrown when <paramref name="services" /> is <see langword="null" />. |
| | | 20 | | /// </exception> |
| | | 21 | | /// <remarks> |
| | | 22 | | /// This helper keeps strict posture explicit in the current 3.x line while giving production hosts a single opt-in |
| | | 23 | | /// fail-closed evaluation posture. It configures options only; hosts still own authentication, authorization, |
| | | 24 | | /// constraint registration, endpoint metadata, persistence, and execution enforcement. |
| | | 25 | | /// </remarks> |
| | | 26 | | public static IServiceCollection AddAsiBackboneStrictGovernance(this IServiceCollection services) |
| | | 27 | | { |
| | 8 | 28 | | ArgumentNullException.ThrowIfNull(services); |
| | | 29 | | |
| | 8 | 30 | | _ = services.AddOptions<AsiBackbonePolicyEvaluatorOptions>() |
| | 8 | 31 | | .Configure(ApplyStrictPolicyEvaluatorProfile) |
| | 5 | 32 | | .Validate(static options => ValidateOptions(options), "Policy evaluator options must be valid.") |
| | 8 | 33 | | .ValidateOnStart(); |
| | | 34 | | |
| | 8 | 35 | | _ = services.AddOptions<AsiBackboneEndpointGovernanceOptions>() |
| | 8 | 36 | | .Configure(ApplyStrictEndpointGovernanceProfile) |
| | 6 | 37 | | .Validate(static options => ValidateOptions(options), "Endpoint governance options must be valid.") |
| | 8 | 38 | | .ValidateOnStart(); |
| | | 39 | | |
| | 8 | 40 | | return services; |
| | | 41 | | } |
| | | 42 | | |
| | | 43 | | /// <summary> |
| | | 44 | | /// Applies the strict governance profile through the explicit <c>AddAsiBackbone</c> builder facade. |
| | | 45 | | /// </summary> |
| | | 46 | | /// <param name="builder">The AsiBackbone builder facade being configured.</param> |
| | | 47 | | /// <returns>The same builder so calls can be chained.</returns> |
| | | 48 | | /// <exception cref="ArgumentNullException"> |
| | | 49 | | /// Thrown when <paramref name="builder" /> is <see langword="null" />. |
| | | 50 | | /// </exception> |
| | | 51 | | public static IAsiBackboneBuilder UseStrictGovernanceProfile(this IAsiBackboneBuilder builder) |
| | | 52 | | { |
| | 1 | 53 | | ArgumentNullException.ThrowIfNull(builder); |
| | | 54 | | |
| | 1 | 55 | | _ = builder.Services.AddAsiBackboneStrictGovernance(); |
| | 1 | 56 | | return builder; |
| | | 57 | | } |
| | | 58 | | |
| | | 59 | | private static void ApplyStrictPolicyEvaluatorProfile(AsiBackbonePolicyEvaluatorOptions options) |
| | | 60 | | { |
| | 5 | 61 | | options.DenyWhenNoConstraints = true; |
| | 5 | 62 | | options.TreatConstraintExceptionAsDenial = true; |
| | 5 | 63 | | options.TreatThreatContributorExceptionAsDenial = true; |
| | 5 | 64 | | options.PreventThreatAssessmentAllowDowngrade = true; |
| | 5 | 65 | | } |
| | | 66 | | |
| | | 67 | | private static void ApplyStrictEndpointGovernanceProfile(AsiBackboneEndpointGovernanceOptions options) |
| | | 68 | | { |
| | 6 | 69 | | options.FailClosedWhenPolicyEvaluatorMissing = true; |
| | 6 | 70 | | options.FailClosedWhenCapabilityValidatorMissing = true; |
| | 6 | 71 | | options.FailClosedWhenAuditSinkMissing = true; |
| | 6 | 72 | | options.RequireGovernanceMetadata = true; |
| | 6 | 73 | | options.IncludeDevelopmentDiagnosticsMetadataValues = false; |
| | 6 | 74 | | } |
| | | 75 | | |
| | | 76 | | private static bool ValidateOptions(AsiBackbonePolicyEvaluatorOptions options) |
| | | 77 | | { |
| | | 78 | | try |
| | | 79 | | { |
| | 5 | 80 | | options.Validate(); |
| | 5 | 81 | | return true; |
| | | 82 | | } |
| | 0 | 83 | | catch (InvalidOperationException) |
| | | 84 | | { |
| | 0 | 85 | | return false; |
| | | 86 | | } |
| | 5 | 87 | | } |
| | | 88 | | |
| | | 89 | | private static bool ValidateOptions(AsiBackboneEndpointGovernanceOptions options) |
| | | 90 | | { |
| | | 91 | | try |
| | | 92 | | { |
| | 6 | 93 | | options.Validate(); |
| | 6 | 94 | | return true; |
| | | 95 | | } |
| | 0 | 96 | | catch (InvalidOperationException) |
| | | 97 | | { |
| | 0 | 98 | | return false; |
| | | 99 | | } |
| | 6 | 100 | | } |
| | | 101 | | } |