@wildo-ai/saas-models 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/applications/applications-context.schemas.d.ts +16 -10
- package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/applications/applications.shared.resources-config.schemas.js +4 -3
- package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.js +36 -0
- package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-account.shared.schemas.js +8 -1
- package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts +0 -4
- package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-configuration.shared.schemas.js +59 -17
- package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts +77 -21
- package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/billing-enums.shared.schemas.js +85 -23
- package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
- package/dist/esm/billing/billing-types.shared.schemas.d.ts +5 -5
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js +39 -0
- package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
- package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
- package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js +35 -0
- package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/invoice-ref.shared.schemas.js +8 -3
- package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
- package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/price.shared.schemas.js +7 -1
- package/dist/esm/billing/price.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js +52 -11
- package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
- package/dist/esm/billing/product-definition.shared.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.resources-config.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.schemas.d.ts +2 -2
- package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/product.shared.schemas.js +7 -3
- package/dist/esm/billing/product.shared.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +2 -2
- package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js +54 -1
- package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
- package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/subscription.shared.schemas.js +6 -2
- package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.js +39 -0
- package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.d.ts +11 -7
- package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
- package/dist/esm/billing/usage-record.shared.schemas.js +29 -6
- package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts +69 -2
- package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js +20 -1
- package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts +85 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js +157 -0
- package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js +35 -2
- package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts +23 -0
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js +56 -0
- package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +541 -20
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +605 -23
- package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +96 -3
- package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
- package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
- package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +94 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +211 -0
- package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +95 -8
- package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts +17 -0
- package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js +27 -4
- package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +89 -16
- package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js +101 -15
- package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js +12 -5
- package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts +21 -0
- package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/analytics-value-moments.shared.schemas.js +20 -0
- package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +9 -5
- package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
- package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts +8 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
- package/dist/esm/config/auth-config-resolution.shared.utils.js +29 -0
- package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts +95 -17
- package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/entity-identity-config.shared.schemas.js +86 -8
- package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
- package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts +12 -12
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
- package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
- package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +40 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +40 -1
- package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +57 -11
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +109 -64
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +200 -19
- package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts +15 -3
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +32 -7
- package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +84 -7
- package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts +59 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js +61 -0
- package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts +97 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js +41 -0
- package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -0
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts +148 -2
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js +56 -1
- package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +9 -31
- package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-capability.shared.schemas.js +8 -5
- package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts +18 -8
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js +9 -4
- package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts +338 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js +332 -0
- package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -0
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts +178 -9
- package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js +181 -9
- package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts +7 -5
- package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js +7 -5
- package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts +40 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js +80 -0
- package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -0
- package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
- package/dist/esm/features/core-feature-definitions.shared.js +7 -1
- package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
- package/dist/esm/features/feature-builders.shared.d.ts +32 -0
- package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
- package/dist/esm/features/feature-builders.shared.js +32 -0
- package/dist/esm/features/feature-builders.shared.js.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/features/user-features.shared.resources-config.schemas.js +48 -0
- package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +156 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.js +175 -0
- package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
- package/dist/esm/files/files.shared.schemas.d.ts +52 -4
- package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
- package/dist/esm/files/files.shared.schemas.js +55 -4
- package/dist/esm/files/files.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js +33 -0
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js +6 -2
- package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js +53 -0
- package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/actors.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts +54 -5
- package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/apps-blueprint/apps-blueprint.shared.schemas.d.ts +6 -6
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts +0 -3
- package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/deliberation.shared.schemas.js +0 -5
- package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js +43 -0
- package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts +14 -0
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +48 -6
- package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js +41 -0
- package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts +0 -7
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js +23 -13
- package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts +19 -0
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js +33 -0
- package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts +14 -9
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js +14 -9
- package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/flows.shared.schemas.js +3 -2
- package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts +128 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js +142 -0
- package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -0
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts +0 -3
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js +1 -4
- package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts +0 -16
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js +1 -17
- package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts +3 -3
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js +3 -3
- package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts +2 -8
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js +4 -15
- package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js +51 -0
- package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.schemas.js +8 -2
- package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
- package/dist/esm/guidance/guidance-state.shared.utils.js +1 -0
- package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js +51 -0
- package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/lifecycle-state.shared.schemas.js +28 -3
- package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +9 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js +51 -0
- package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts +46 -0
- package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
- package/dist/esm/guidance/progression-state.shared.schemas.js +67 -4
- package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +356 -52
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +166 -39
- package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
- package/dist/esm/index.d.ts +15 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts +11 -2
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts +15 -0
- package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
- package/dist/esm/notifications/email/email-template.shared.enums.js +15 -0
- package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
- package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js +19 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts +30 -0
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js +65 -1
- package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts +6 -4
- package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.core.definitions.js +6 -4
- package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.d.ts +167 -5
- package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.schemas.js +191 -6
- package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js +36 -0
- package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.d.ts +107 -0
- package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/notifications/notifications.shared.schemas.js +149 -1
- package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js +44 -0
- package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-members.shared.schemas.js +15 -4
- package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js +22 -1
- package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts +26 -0
- package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-preferences.shared.schemas.js +25 -0
- package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts +25 -0
- package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organization-profile.shared.schemas.js +42 -17
- package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts +3 -2
- package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
- package/dist/esm/organizations/organization-unit-narrowing.shared.js +9 -2
- package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +35 -12
- package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/public-runtime/index.d.ts +49 -2
- package/dist/esm/public-runtime/index.d.ts.map +1 -1
- package/dist/esm/public-runtime/index.js +48 -1
- package/dist/esm/public-runtime/index.js.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts +6 -5
- package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js +23 -5
- package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.d.ts +16 -3
- package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
- package/dist/esm/queue/jobs.shared.schemas.js +16 -3
- package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts +137 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.js +1201 -0
- package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -0
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts +67 -0
- package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
- package/dist/esm/requests/manual-controllers-routes-urls.js +78 -0
- package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts +11 -1
- package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js +11 -1
- package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.d.ts +86 -4
- package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
- package/dist/esm/requests/websocket.shared.schemas.js +138 -0
- package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
- package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
- package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
- package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
- package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
- package/dist/esm/resources/resources-config.shared.factory.d.ts +1 -0
- package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.factory.js +189 -31
- package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.d.ts +395 -92
- package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
- package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources-registry.shared.core.definitions.js +97 -5
- package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
- package/dist/esm/resources/resources-relationships.shared.factory.js +15 -0
- package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.d.ts +37 -0
- package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.core.definitions.js +51 -0
- package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.d.ts +11 -2
- package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
- package/dist/esm/resources/resources.shared.schemas.js +34 -3
- package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts +51 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.js +53 -0
- package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -0
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +21 -6
- package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.d.ts +16 -2
- package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/resources-summary.utils.js +19 -5
- package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js +11 -0
- package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts +25 -0
- package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js +38 -0
- package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts +1 -0
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js +38 -0
- package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts +4 -11
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js +0 -1
- package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +141 -5
- package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/authentication.shared.schemas.js +147 -3
- package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/consumable-token.shared.schemas.js +16 -0
- package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
- package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts +1 -0
- package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js +11 -0
- package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts +15 -0
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js +21 -4
- package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
- package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts +61 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js +208 -6
- package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts +37 -27
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js +134 -12
- package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts +0 -6
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js +17 -8
- package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +70 -0
- package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +45 -8
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +56 -10
- package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
- package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
- package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
- package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts +31 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js +198 -0
- package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts +31 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js +191 -0
- package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts +250 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js +486 -0
- package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -0
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts +4 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js +29 -0
- package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts +4 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js +29 -0
- package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +67 -0
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +44 -1
- package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js +35 -0
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts +13 -0
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +31 -4
- package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js +34 -0
- package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/inbound-contacts.shared.schemas.js +7 -4
- package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.js +37 -0
- package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-credentials.shared.schemas.js +17 -2
- package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js +36 -0
- package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-identity-links.shared.schemas.js +15 -5
- package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +5 -5
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.js +53 -0
- package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.js +62 -0
- package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +5 -5
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js +53 -0
- package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js +62 -0
- package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/user-self.shared.resources-config.schemas.js +33 -3
- package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts +17 -1
- package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.resources-config.schemas.js +136 -5
- package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
- package/dist/esm/users/users.shared.schemas.d.ts +62 -12
- package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
- package/dist/esm/users/users.shared.schemas.js +79 -23
- package/dist/esm/users/users.shared.schemas.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -6
- package/dist/esm/.builder.pid +0 -9
package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js
CHANGED
|
@@ -20,6 +20,7 @@ import { createResourceConfiguration_Initialization } from '../../resources/reso
|
|
|
20
20
|
import { ResourceSystemAccessMode } from '../../resources/resources-config.shared.schemas.js';
|
|
21
21
|
import { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../../notifications/notifications.shared.schemas.js';
|
|
22
22
|
import { CORE_APP_ROLES, CORE_ORG_ROLES } from './roles.shared.schemas.js';
|
|
23
|
+
import { ErasureRetentionMode, ResourceDataSubjectKind } from '../../compliance/privacy/impersonalization.shared.schemas.js';
|
|
23
24
|
export const platformAccessGrantsResourceConfiguration_InitializationFactory = (resourcesRelationships) => createResourceConfiguration_Initialization({
|
|
24
25
|
mainSchema: PlatformAccessGrantSchema,
|
|
25
26
|
resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,
|
|
@@ -56,14 +57,56 @@ export const platformAccessGrantsResourceConfiguration_InitializationFactory = (
|
|
|
56
57
|
*/
|
|
57
58
|
exportSubject: ResourceSystemAccessMode.FORBIDDEN,
|
|
58
59
|
},
|
|
60
|
+
/**
|
|
61
|
+
* Subject erasure RETAINS this row and scrubs its free text.
|
|
62
|
+
*
|
|
63
|
+
* Note this is a DIFFERENT question from the `exportSubject: FORBIDDEN` above, and the two answers
|
|
64
|
+
* differ deliberately. That one asks whether the monitored operator may READ the monitoring trail —
|
|
65
|
+
* no. This one asks what erasure DOES to the row, and nothing here says erasure must not reach it.
|
|
66
|
+
*
|
|
67
|
+
* The grant survives because its security value is WHO reached WHICH tenant, WHEN, and under whose
|
|
68
|
+
* approval — none of which is scrubbed. What does not survive is `justification` and `decisionReason`:
|
|
69
|
+
* operator- and approver-written prose, and the surface most likely to name a third party in passing.
|
|
70
|
+
* That makes the erasure narrow rather than destructive of the record.
|
|
71
|
+
*
|
|
72
|
+
* Contrast `auditLogs`, which is exempt outright: it is the immutable ledger of what happened,
|
|
73
|
+
* including this erasure, so scrubbing it would destroy the evidence the erasure was performed.
|
|
74
|
+
*/
|
|
75
|
+
retentionPolicy: {
|
|
76
|
+
mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Erasing one of these rows revokes NO session. The grant is a record ABOUT an operator's access, not
|
|
80
|
+
* the operator; their session ends through the `USERS` row, which is `SELF_PRINCIPAL`.
|
|
81
|
+
*/
|
|
82
|
+
dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },
|
|
59
83
|
coreOperations: [
|
|
60
84
|
CoreResourceOperation.READ,
|
|
61
85
|
CoreResourceOperation.LIST,
|
|
62
86
|
CoreResourceOperation.COUNT,
|
|
87
|
+
// Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.
|
|
88
|
+
CoreResourceOperation.UPDATE_MANY,
|
|
63
89
|
// Present for the tenant-purge cascade ONLY — see the operation's configuration below.
|
|
64
90
|
CoreResourceOperation.DELETE,
|
|
65
91
|
],
|
|
66
92
|
operationsConfiguration: {
|
|
93
|
+
/*
|
|
94
|
+
|
|
95
|
+
* Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY: the
|
|
96
|
+
|
|
97
|
+
* retention primitives resolve through `getServiceOperationPathDefault`, which matches only
|
|
98
|
+
|
|
99
|
+
* INTERNAL_CALL / API_CALL. CRITICAL — it is the verb the impersonalize writer uses to stamp markers.
|
|
100
|
+
|
|
101
|
+
*/
|
|
102
|
+
[CoreResourceOperation.UPDATE_MANY]: {
|
|
103
|
+
variants: [{
|
|
104
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
105
|
+
isDefault: true,
|
|
106
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
107
|
+
riskLevel: ResourceOperationRiskLevel.CRITICAL,
|
|
108
|
+
}],
|
|
109
|
+
},
|
|
67
110
|
[CoreResourceOperation.READ]: {
|
|
68
111
|
variants: [
|
|
69
112
|
{
|
|
@@ -226,6 +269,33 @@ export const platformAccessGrantsResourceConfiguration_InitializationFactory = (
|
|
|
226
269
|
* Revoking is monotonic — it only ever removes authority — so admitting the platform side costs
|
|
227
270
|
* nothing the reversibility test would object to.
|
|
228
271
|
*/
|
|
272
|
+
/**
|
|
273
|
+
* ACTIVE → EXPIRED once the window has elapsed, dispatched by the credential-expiry sweep and
|
|
274
|
+
* by nothing else (#413). INTERNAL_CALL: no route, no frontend affordance, and therefore no
|
|
275
|
+
* `admitsCrossTenantPlatformAdministration` — the tenant-boundary question does not arise for
|
|
276
|
+
* an operation no request can reach.
|
|
277
|
+
*
|
|
278
|
+
* The transition precondition lives in the paired implementation, which permits it only from
|
|
279
|
+
* ACTIVE: a grant the tenant DENIED or REVOKED must keep saying so, and relabelling a
|
|
280
|
+
* terminal grant would rewrite the decision history a customer audit reads.
|
|
281
|
+
*/
|
|
282
|
+
[PlatformAccessGrants_Operations.EXPIRE]: {
|
|
283
|
+
variants: [
|
|
284
|
+
{
|
|
285
|
+
variantType: ResourceOperationVariantType.INTERNAL_CALL,
|
|
286
|
+
isDefault: true,
|
|
287
|
+
roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
|
|
288
|
+
riskLevel: ResourceOperationRiskLevel.LOW,
|
|
289
|
+
resourceOperationLike: CoreResourceOperation.UPDATE,
|
|
290
|
+
// EMPTY BY CONTRACT, not by omission. The credential-expiry sweep dispatches this verb with `{}`
|
|
291
|
+
// and the paired prefix implementation forces the status transition itself, so there is no field
|
|
292
|
+
// a caller may supply. Declaring nothing is NOT the same as declaring this: an operation without
|
|
293
|
+
// a `requestDto` inherits the resource's ENTIRE update contract, which would let an INTERNAL_CALL
|
|
294
|
+
// that accepts nothing advertise every field — `status` included, the one field this verb owns.
|
|
295
|
+
requestDto: z.object({}),
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
},
|
|
229
299
|
[PlatformAccessGrants_Operations.REVOKE]: {
|
|
230
300
|
variants: [
|
|
231
301
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-access-grants.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Platform Access Grants — resource configuration.\n *\n * The operation set is unusual and the asymmetry is the point: the PLATFORM requests, the TENANT\n * decides. No verb lets one side do the other's job.\n *\n * requestAccess — platform-tier, crosses the tenant boundary\n * approve / deny — the TARGET tenant's own administrators, never platform-tier\n * revoke — either side, because either may end an elevation early\n *\n * See `platform-access-grants.shared.schemas.ts` for why the resource exists at all (rungs 4–5 of\n * the operator-access ladder in `.claude/rules/administrative-continuity-floors.md`) and\n * `.claude/plans/platform-access-grants-jit-elevation.md` for the remaining steps.\n */\n\nimport { z } from 'zod';\nimport { PlatformAccessGrantSchema, PlatformAccessGrantStatus, PlatformAccessGrants_Operations } from './platform-access-grants.shared.schemas';\nimport { CoreResourceOperation, CoreResourceType, coreResourceShared_FieldIdentifier } from '../../resources/resources.shared.core.definitions';\nimport {\n ResourceOperationRiskLevel,\n ResourceOperationVariantType,\n type ResourceRelationship,\n} from '../../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../../resources/resources-config.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../../notifications/notifications.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from './roles.shared.schemas';\n\n\ntype PlatformAccessGrantsCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.COUNT\n | CoreResourceOperation.DELETE;\n\nexport const platformAccessGrantsResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) =>\n createResourceConfiguration_Initialization<\n typeof PlatformAccessGrants_Operations,\n PlatformAccessGrantsCoreOperations,\n typeof PlatformAccessGrantSchema\n >({\n mainSchema: PlatformAccessGrantSchema,\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.PLATFORM_ACCESS_GRANTS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /**\n * `read`/`list` are ALLOWED for the trusted path because the authorization layer itself has to\n * resolve a caller's usable grant before admitting a crossing, and it does so on a system context\n * — the caller is by definition not a member of the tenant whose grants are being read.\n *\n * No trusted `create`/`update`: every transition belongs to a custom implementation that applies\n * the tenant policy and the continuity-floor measurement. A system door around those would be a\n * second way to mint an elevation, which is the one thing this resource exists to prevent.\n */\n systemAccessPolicy: {\n read: ResourceSystemAccessMode.ALLOWED,\n list: ResourceSystemAccessMode.ALLOWED,\n\n /**\n * Subject-export disclosure — FORBIDDEN, and the declaration is REQUIRED rather than optional.\n *\n * `operatorUserId` and `approvedByUserId` are foreign keys back to USERS, so\n * `classifySubjectExportDisposition` puts these rows on a user's Art. 15 graph as\n * `INCLUDED_REFERENCES_SUBJECT` — personal data CONCERNING the subject even though the subject\n * does not own it. An included resource carrying NO declaration REFUSES the entire export, so\n * omitting this would trade a frontend boot failure for a broken disclosure right.\n *\n * FORBIDDEN for the reason AUDIT_LOGS is: this is a security/operational monitoring record, and\n * handing the monitoring trail to the person it monitors is self-defeating. It is also not only\n * about them — a grant names the TENANT's approver and carries the tenant's decision reason, so\n * disclosing it to the operator would expose another data subject's decision (Art. 15(4)).\n * FORBIDDEN rows are left OUT of the bundle and RECORDED with that reason, never silently\n * dropped, so the report still answers \"why is this missing?\".\n */\n exportSubject: ResourceSystemAccessMode.FORBIDDEN,\n },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.COUNT,\n // Present for the tenant-purge cascade ONLY — see the operation's configuration below.\n CoreResourceOperation.DELETE,\n ],\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Both sides read the same row through the same door: a tenant admin sees elevations\n // raised against their tenant (the consent record is worthless if the consenting party\n // cannot see it), and the platform sees the ones it raised. The ORGANIZATIONS scope does\n // the tenant separation; the platform reaches it through the cross-tenant admission on\n // the verbs below.\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n [CoreResourceOperation.COUNT]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n /**\n * PURGE ONLY — there is deliberately no `API_CALL` variant, so no client can delete a grant.\n *\n * The verb exists because grants are a COMPOSITION child of ORGANIZATIONS with\n * `onParentDelete` enabled, and a cascade can only call an operation the child actually\n * declares. Without it the registry's composition-cascade-deletability guard fails — correctly:\n * the cascade would have been declared and then silently unable to run, leaving grant rows\n * behind after their tenant was purged.\n *\n * Route-less is the whole point of the shape. `INTERNAL_CALL` mirrors `organizations.delete`'s\n * own default: the tenant purge may remove these rows, and nobody else may. Erasing a consent\n * record through an API would let either party rewrite the history of an access decision, which\n * is exactly what this resource exists to make impossible.\n */\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n\n /**\n * The bootstrap verb, and the ONE operation here that must stay reachable without an existing\n * grant — otherwise the mechanism cannot start: an operator would need an elevation to request\n * an elevation. It therefore declares `admitsCrossTenantPlatformAdministration` and must be\n * explicitly exempted when the admission predicate later starts requiring a usable grant\n * (Step 4 of the plan). That exemption is load-bearing and gets its own pin.\n *\n * What keeps the exemption safe is that requesting is not accessing: this verb writes a row in\n * `PENDING_APPROVAL` (or `ACTIVE` when the tenant has not opted into approval) and touches\n * nothing else in the tenant. The blast radius of an abused request is a notification and an\n * audit row naming the operator.\n *\n * assurance-control: WILDO.ACCESS.CROSS_TENANT_ADMINISTRATION — elevation is requested, never assumed.\n * assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE\n */\n [PlatformAccessGrants_Operations.REQUEST_ACCESS]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.CREATE,\n admitsCrossTenantPlatformAdministration: true,\n /**\n * `organizationId` deliberately does NOT appear in this body DTO. The organization is\n * already the mandatory primary-scope path segment and the execution-context creator\n * validates that URL value before dispatch. Requiring it again in JSON made clients\n * author the same security-critical target twice and created an avoidable mismatch case.\n *\n * WHERE AN OPERATOR GETS the path id is still a deliberate product decision. There is\n * no in-product surface that lists organizations the operator does not belong to:\n * `organizations | LIST` is confined to the caller's own memberships. The id therefore\n * arrives with the customer support case, where it is also present in support URLs,\n * organization notifications and the audit trail.\n *\n * Do not widen `organizations | LIST` to make discovery convenient: a browsable\n * directory is the customer list and would restore the standing cross-tenant\n * visibility this workflow exists to avoid.\n */\n requestDto: z.object({\n justification: z.string().min(1).max(1000),\n /** Minutes. Clamped server-side to the 4h ceiling; a longer ask is not refused. */\n requestedDurationMinutes: z.number().int().positive().optional(),\n }),\n },\n ],\n userNotifications: [\n {\n // The tenant learns immediately that an operator asked for access — before it happens,\n // not after. Under the approval posture this notification IS the request; without it,\n // opting in would give a tenant a decision it never hears about.\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n },\n ],\n },\n\n /**\n * The tenant's decision. Gated on the TENANT's own roles and deliberately NOT reachable by the\n * platform: an operator who could approve their own request would make the whole Lockbox\n * posture ceremonial. Note the absence of `admitsCrossTenantPlatformAdministration` here — that\n * absence is the control, so do not add it \"for symmetry\".\n */\n [PlatformAccessGrants_Operations.APPROVE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n // Only a request still awaiting a decision can be decided. Fails closed server-side, so a\n // replayed approval cannot revive a denied, revoked or expired grant.\n enabledCondition: ({ currentObject }) => currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL,\n },\n ],\n },\n\n [PlatformAccessGrants_Operations.DENY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n enabledCondition: ({ currentObject }) => currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL,\n },\n ],\n },\n\n /**\n * Ending an elevation early. Reachable by BOTH sides, which is why it carries the cross-tenant\n * admission while `approve`/`deny` do not: a tenant revokes access it granted, and an operator\n * closes out their own session rather than leaving a live window open until it lapses.\n *\n * Revoking is monotonic — it only ever removes authority — so admitting the platform side costs\n * nothing the reversibility test would object to.\n */\n [PlatformAccessGrants_Operations.REVOKE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n admitsCrossTenantPlatformAdministration: true,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n enabledCondition: ({ currentObject }) =>\n currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL\n || currentObject.status === PlatformAccessGrantStatus.ACTIVE,\n },\n ],\n },\n },\n // NOTE: the ORGANIZATIONS primary scope is NOT declared here. It is derived from the registry\n // relationship carrying `isPrimaryScope: true` (ORGANIZATIONS → PLATFORM_ACCESS_GRANTS), which is\n // the single place scope is expressed for every resource. Declaring it twice would let the two\n // drift, and the relationship is the one the authorizer actually reads.\n });\n"]}
|
|
1
|
+
{"version":3,"file":"platform-access-grants.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Platform Access Grants — resource configuration.\n *\n * The operation set is unusual and the asymmetry is the point: the PLATFORM requests, the TENANT\n * decides. No verb lets one side do the other's job.\n *\n * requestAccess — platform-tier, crosses the tenant boundary\n * approve / deny — the TARGET tenant's own administrators, never platform-tier\n * revoke — either side, because either may end an elevation early\n *\n * See `platform-access-grants.shared.schemas.ts` for why the resource exists at all (rungs 4–5 of\n * the operator-access ladder in `.claude/rules/administrative-continuity-floors.md`) and\n * `.claude/plans/platform-access-grants-jit-elevation.md` for the remaining steps.\n */\n\nimport { z } from 'zod';\nimport { PlatformAccessGrantSchema, PlatformAccessGrantStatus, PlatformAccessGrants_Operations } from './platform-access-grants.shared.schemas';\nimport { CoreResourceOperation, CoreResourceType, coreResourceShared_FieldIdentifier } from '../../resources/resources.shared.core.definitions';\nimport {\n ResourceOperationRiskLevel,\n ResourceOperationVariantType,\n type ResourceRelationship,\n} from '../../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../../resources/resources-config.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../../notifications/notifications.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from './roles.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../../compliance/privacy/impersonalization.shared.schemas';\n\n\ntype PlatformAccessGrantsCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.COUNT\n | CoreResourceOperation.DELETE\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.UPDATE_MANY;\n\nexport const platformAccessGrantsResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) =>\n createResourceConfiguration_Initialization<\n typeof PlatformAccessGrants_Operations,\n PlatformAccessGrantsCoreOperations,\n typeof PlatformAccessGrantSchema\n >({\n mainSchema: PlatformAccessGrantSchema,\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.PLATFORM_ACCESS_GRANTS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /**\n * `read`/`list` are ALLOWED for the trusted path because the authorization layer itself has to\n * resolve a caller's usable grant before admitting a crossing, and it does so on a system context\n * — the caller is by definition not a member of the tenant whose grants are being read.\n *\n * No trusted `create`/`update`: every transition belongs to a custom implementation that applies\n * the tenant policy and the continuity-floor measurement. A system door around those would be a\n * second way to mint an elevation, which is the one thing this resource exists to prevent.\n */\n systemAccessPolicy: {\n read: ResourceSystemAccessMode.ALLOWED,\n list: ResourceSystemAccessMode.ALLOWED,\n\n /**\n * Subject-export disclosure — FORBIDDEN, and the declaration is REQUIRED rather than optional.\n *\n * `operatorUserId` and `approvedByUserId` are foreign keys back to USERS, so\n * `classifySubjectExportDisposition` puts these rows on a user's Art. 15 graph as\n * `INCLUDED_REFERENCES_SUBJECT` — personal data CONCERNING the subject even though the subject\n * does not own it. An included resource carrying NO declaration REFUSES the entire export, so\n * omitting this would trade a frontend boot failure for a broken disclosure right.\n *\n * FORBIDDEN for the reason AUDIT_LOGS is: this is a security/operational monitoring record, and\n * handing the monitoring trail to the person it monitors is self-defeating. It is also not only\n * about them — a grant names the TENANT's approver and carries the tenant's decision reason, so\n * disclosing it to the operator would expose another data subject's decision (Art. 15(4)).\n * FORBIDDEN rows are left OUT of the bundle and RECORDED with that reason, never silently\n * dropped, so the report still answers \"why is this missing?\".\n */\n exportSubject: ResourceSystemAccessMode.FORBIDDEN,\n },\n\n /**\n * Subject erasure RETAINS this row and scrubs its free text.\n *\n * Note this is a DIFFERENT question from the `exportSubject: FORBIDDEN` above, and the two answers\n * differ deliberately. That one asks whether the monitored operator may READ the monitoring trail —\n * no. This one asks what erasure DOES to the row, and nothing here says erasure must not reach it.\n *\n * The grant survives because its security value is WHO reached WHICH tenant, WHEN, and under whose\n * approval — none of which is scrubbed. What does not survive is `justification` and `decisionReason`:\n * operator- and approver-written prose, and the surface most likely to name a third party in passing.\n * That makes the erasure narrow rather than destructive of the record.\n *\n * Contrast `auditLogs`, which is exempt outright: it is the immutable ledger of what happened,\n * including this erasure, so scrubbing it would destroy the evidence the erasure was performed.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. The grant is a record ABOUT an operator's access, not\n * the operator; their session ends through the `USERS` row, which is `SELF_PRINCIPAL`.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.COUNT,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n CoreResourceOperation.UPDATE_MANY,\n // Present for the tenant-purge cascade ONLY — see the operation's configuration below.\n CoreResourceOperation.DELETE,\n ],\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY: the\n\n * retention primitives resolve through `getServiceOperationPathDefault`, which matches only\n\n * INTERNAL_CALL / API_CALL. CRITICAL — it is the verb the impersonalize writer uses to stamp markers.\n\n */\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n // Both sides read the same row through the same door: a tenant admin sees elevations\n // raised against their tenant (the consent record is worthless if the consenting party\n // cannot see it), and the platform sees the ones it raised. The ORGANIZATIONS scope does\n // the tenant separation; the platform reaches it through the cross-tenant admission on\n // the verbs below.\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n [CoreResourceOperation.COUNT]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n\n /**\n * PURGE ONLY — there is deliberately no `API_CALL` variant, so no client can delete a grant.\n *\n * The verb exists because grants are a COMPOSITION child of ORGANIZATIONS with\n * `onParentDelete` enabled, and a cascade can only call an operation the child actually\n * declares. Without it the registry's composition-cascade-deletability guard fails — correctly:\n * the cascade would have been declared and then silently unable to run, leaving grant rows\n * behind after their tenant was purged.\n *\n * Route-less is the whole point of the shape. `INTERNAL_CALL` mirrors `organizations.delete`'s\n * own default: the tenant purge may remove these rows, and nobody else may. Erasing a consent\n * record through an API would let either party rewrite the history of an access decision, which\n * is exactly what this resource exists to make impossible.\n */\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n\n /**\n * The bootstrap verb, and the ONE operation here that must stay reachable without an existing\n * grant — otherwise the mechanism cannot start: an operator would need an elevation to request\n * an elevation. It therefore declares `admitsCrossTenantPlatformAdministration` and must be\n * explicitly exempted when the admission predicate later starts requiring a usable grant\n * (Step 4 of the plan). That exemption is load-bearing and gets its own pin.\n *\n * What keeps the exemption safe is that requesting is not accessing: this verb writes a row in\n * `PENDING_APPROVAL` (or `ACTIVE` when the tenant has not opted into approval) and touches\n * nothing else in the tenant. The blast radius of an abused request is a notification and an\n * audit row naming the operator.\n *\n * assurance-control: WILDO.ACCESS.CROSS_TENANT_ADMINISTRATION — elevation is requested, never assumed.\n * assurance-control: WILDO.ACCESS.PRIVILEGE_EVIDENCE\n */\n [PlatformAccessGrants_Operations.REQUEST_ACCESS]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n resourceOperationLike: CoreResourceOperation.CREATE,\n admitsCrossTenantPlatformAdministration: true,\n /**\n * `organizationId` deliberately does NOT appear in this body DTO. The organization is\n * already the mandatory primary-scope path segment and the execution-context creator\n * validates that URL value before dispatch. Requiring it again in JSON made clients\n * author the same security-critical target twice and created an avoidable mismatch case.\n *\n * WHERE AN OPERATOR GETS the path id is still a deliberate product decision. There is\n * no in-product surface that lists organizations the operator does not belong to:\n * `organizations | LIST` is confined to the caller's own memberships. The id therefore\n * arrives with the customer support case, where it is also present in support URLs,\n * organization notifications and the audit trail.\n *\n * Do not widen `organizations | LIST` to make discovery convenient: a browsable\n * directory is the customer list and would restore the standing cross-tenant\n * visibility this workflow exists to avoid.\n */\n requestDto: z.object({\n justification: z.string().min(1).max(1000),\n /** Minutes. Clamped server-side to the 4h ceiling; a longer ask is not refused. */\n requestedDurationMinutes: z.number().int().positive().optional(),\n }),\n },\n ],\n userNotifications: [\n {\n // The tenant learns immediately that an operator asked for access — before it happens,\n // not after. Under the approval posture this notification IS the request; without it,\n // opting in would give a tenant a decision it never hears about.\n target: CoreUserNotificationTarget.ORGANIZATION_USERS,\n channel: CoreUserNotificationChannel.EMAIL,\n },\n ],\n },\n\n /**\n * The tenant's decision. Gated on the TENANT's own roles and deliberately NOT reachable by the\n * platform: an operator who could approve their own request would make the whole Lockbox\n * posture ceremonial. Note the absence of `admitsCrossTenantPlatformAdministration` here — that\n * absence is the control, so do not add it \"for symmetry\".\n */\n [PlatformAccessGrants_Operations.APPROVE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n // Only a request still awaiting a decision can be decided. Fails closed server-side, so a\n // replayed approval cannot revive a denied, revoked or expired grant.\n enabledCondition: ({ currentObject }) => currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL,\n },\n ],\n },\n\n [PlatformAccessGrants_Operations.DENY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n enabledCondition: ({ currentObject }) => currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL,\n },\n ],\n },\n\n /**\n * Ending an elevation early. Reachable by BOTH sides, which is why it carries the cross-tenant\n * admission while `approve`/`deny` do not: a tenant revokes access it granted, and an operator\n * closes out their own session rather than leaving a live window open until it lapses.\n *\n * Revoking is monotonic — it only ever removes authority — so admitting the platform side costs\n * nothing the reversibility test would object to.\n */\n /**\n * ACTIVE → EXPIRED once the window has elapsed, dispatched by the credential-expiry sweep and\n * by nothing else (#413). INTERNAL_CALL: no route, no frontend affordance, and therefore no\n * `admitsCrossTenantPlatformAdministration` — the tenant-boundary question does not arise for\n * an operation no request can reach.\n *\n * The transition precondition lives in the paired implementation, which permits it only from\n * ACTIVE: a grant the tenant DENIED or REVOKED must keep saying so, and relabelling a\n * terminal grant would rewrite the decision history a customer audit reads.\n */\n [PlatformAccessGrants_Operations.EXPIRE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n // EMPTY BY CONTRACT, not by omission. The credential-expiry sweep dispatches this verb with `{}`\n // and the paired prefix implementation forces the status transition itself, so there is no field\n // a caller may supply. Declaring nothing is NOT the same as declaring this: an operation without\n // a `requestDto` inherits the resource's ENTIRE update contract, which would let an INTERNAL_CALL\n // that accepts nothing advertise every field — `status` included, the one field this verb owns.\n requestDto: z.object({}),\n },\n ],\n },\n\n [PlatformAccessGrants_Operations.REVOKE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n resourceOperationLike: CoreResourceOperation.UPDATE,\n admitsCrossTenantPlatformAdministration: true,\n requestDto: z.object({\n decisionReason: z.string().max(1000).optional(),\n }),\n enabledCondition: ({ currentObject }) =>\n currentObject.status === PlatformAccessGrantStatus.PENDING_APPROVAL\n || currentObject.status === PlatformAccessGrantStatus.ACTIVE,\n },\n ],\n },\n },\n // NOTE: the ORGANIZATIONS primary scope is NOT declared here. It is derived from the registry\n // relationship carrying `isPrimaryScope: true` (ORGANIZATIONS → PLATFORM_ACCESS_GRANTS), which is\n // the single place scope is expressed for every resource. Declaring it twice would let the two\n // drift, and the relationship is the one the authorizer actually reads.\n });\n"]}
|
|
@@ -59,10 +59,14 @@ export declare enum PlatformAccessGrantStatus {
|
|
|
59
59
|
/** The tenant refused. Terminal — a new request must be raised rather than this one retried. */
|
|
60
60
|
DENIED = "denied",
|
|
61
61
|
/**
|
|
62
|
-
* The window elapsed. Terminal, and
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
62
|
+
* The window elapsed. Terminal, and written by the credential-expiry sweep since 2026-09-08
|
|
63
|
+
* (#413) — before that it was reached by NO writer at all, so an elapsed grant read as ACTIVE
|
|
64
|
+
* forever in the customer-facing listing of its own resource.
|
|
65
|
+
*
|
|
66
|
+
* The label is still bookkeeping for humans and reporting, NEVER the control: the admission
|
|
67
|
+
* predicate compares `expiresAt` against now, so an expired grant stops working whether or not
|
|
68
|
+
* the sweep has run. That separation is deliberate and must survive — if admission ever starts
|
|
69
|
+
* reading this label, a lagging sweep becomes an authorization hole rather than a stale display.
|
|
66
70
|
*/
|
|
67
71
|
EXPIRED = "expired",
|
|
68
72
|
/** Withdrawn before expiry, by the tenant or by the platform. Terminal. */
|
|
@@ -80,7 +84,18 @@ export declare enum PlatformAccessGrantLifecycleTransition {
|
|
|
80
84
|
REQUESTED = "requested",
|
|
81
85
|
APPROVED = "approved",
|
|
82
86
|
DENIED = "denied",
|
|
83
|
-
REVOKED = "revoked"
|
|
87
|
+
REVOKED = "revoked",
|
|
88
|
+
/**
|
|
89
|
+
* The window elapsed and the sweep relabelled the grant (#413). The ONE transition with no human
|
|
90
|
+
* actor — every other member records a decision somebody made, so an audit row for this one
|
|
91
|
+
* carries no `decidedByUserId`, and that absence is the fact rather than a gap.
|
|
92
|
+
*
|
|
93
|
+
* It is recorded even though the label is bookkeeping and never the control: a customer reading
|
|
94
|
+
* the history of an operator's access to their tenant should see the access END, and a grant that
|
|
95
|
+
* simply stops appearing as ACTIVE with no corresponding row is the version of that history that
|
|
96
|
+
* raises questions.
|
|
97
|
+
*/
|
|
98
|
+
EXPIRED = "expired"
|
|
84
99
|
}
|
|
85
100
|
/** Why a grant became {@link PlatformAccessGrantStatus.ACTIVE} without a tenant administrator acting. */
|
|
86
101
|
export declare enum PlatformAccessGrantAutoApprovalReason {
|
|
@@ -95,14 +110,30 @@ export declare enum PlatformAccessGrantAutoApprovalReason {
|
|
|
95
110
|
TENANT_CANNOT_APPROVE = "tenant_cannot_approve"
|
|
96
111
|
}
|
|
97
112
|
/**
|
|
98
|
-
* The
|
|
113
|
+
* The default life of a grant whose request names no duration.
|
|
114
|
+
*
|
|
115
|
+
* ONE HOUR, and deliberately far below the ceiling. A request that states no duration is the
|
|
116
|
+
* unconsidered case, and the unconsidered case should get the narrowest window that still works —
|
|
117
|
+
* not the widest the system allows. Until 2026-09-08 this was 240, equal to the maximum, so every
|
|
118
|
+
* grant that did not ask was issued a four-hour elevation; that is the opposite of what a
|
|
119
|
+
* just-in-time mechanism is for.
|
|
120
|
+
*
|
|
121
|
+
* Sixty rather than thirty, and the reasoning is the part worth keeping: the failure mode of a
|
|
122
|
+
* too-short default is not a security one, it is that an operator re-requesting mid-incident learns
|
|
123
|
+
* to ask for the maximum every time — which would restore the old behaviour through the front door
|
|
124
|
+
* and make the ceiling the effective default. An hour covers an ordinary support interaction
|
|
125
|
+
* without teaching that habit. An operator who genuinely needs longer asks, and that ask is the
|
|
126
|
+
* record we want.
|
|
127
|
+
*/
|
|
128
|
+
export declare const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 60;
|
|
129
|
+
/**
|
|
130
|
+
* The maximum life of a grant, whatever a request asks for.
|
|
99
131
|
*
|
|
100
132
|
* Four hours is a working session, not a working week: long enough that an operator is not
|
|
101
133
|
* re-requesting mid-incident, short enough that a forgotten grant is not a standing privilege by
|
|
102
134
|
* another name. Callers may request LESS; the ceiling is enforced server-side so a client cannot
|
|
103
135
|
* mint a long-lived elevation by asking for one.
|
|
104
136
|
*/
|
|
105
|
-
export declare const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 240;
|
|
106
137
|
export declare const PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES = 240;
|
|
107
138
|
/** Statuses from which a grant can still be withdrawn. */
|
|
108
139
|
export declare const PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES: readonly PlatformAccessGrantStatus[];
|
|
@@ -166,6 +197,12 @@ export declare enum PlatformAccessGrants_Operations {
|
|
|
166
197
|
REQUEST_ACCESS = "requestAccess",
|
|
167
198
|
APPROVE = "approve",
|
|
168
199
|
DENY = "deny",
|
|
169
|
-
REVOKE = "revoke"
|
|
200
|
+
REVOKE = "revoke",
|
|
201
|
+
/**
|
|
202
|
+
* ACTIVE → EXPIRED once the window has elapsed, dispatched by the credential-expiry sweep and by
|
|
203
|
+
* nothing else (#413). Not an operator verb: an operator who wants access to end early uses
|
|
204
|
+
* REVOKE, and nobody needs a button that declares a date has passed.
|
|
205
|
+
*/
|
|
206
|
+
EXPIRE = "expire"
|
|
170
207
|
}
|
|
171
208
|
//# sourceMappingURL=platform-access-grants.shared.schemas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-access-grants.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"platform-access-grants.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;GAKG;AACH,oBAAY,yBAAyB;IACnC,wFAAwF;IACxF,gBAAgB,qBAAqB;IACrC,yFAAyF;IACzF,MAAM,WAAW;IACjB,gGAAgG;IAChG,MAAM,WAAW;IACjB;;;;;;;;;OASG;IACH,OAAO,YAAY;IACnB,2EAA2E;IAC3E,OAAO,YAAY;CACpB;AAED;;;;;;;GAOG;AACH,oBAAY,sCAAsC;IAChD,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB;;;;;;;;;OASG;IACH,OAAO,YAAY;CACpB;AAED,yGAAyG;AACzG,oBAAY,qCAAqC;IAC/C,kGAAkG;IAClG,4BAA4B,iCAAiC;IAC7D;;;;;OAKG;IACH,qBAAqB,0BAA0B;CAChD;AAKD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,8CAA8C,KAAK,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,8CAA8C,MAAM,CAAC;AAElE,0DAA0D;AAC1D,eAAO,MAAM,wCAAwC,EAAE,SAAS,yBAAyB,EAGxF,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;iBAiFpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,WAAW,CAAC,GAAG,SAAS,EACpE,GAAG,EAAE,IAAI,GACR,OAAO,CAMT;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,wBAAwB,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAM9G;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,oBAAY,+BAA+B;IACzC,cAAc,kBAAkB;IAChC,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB;;;;OAIG;IACH,MAAM,WAAW;CAClB"}
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
*/
|
|
47
47
|
import { z } from 'zod';
|
|
48
48
|
import { PersonalDataCategory } from '../../compliance/privacy/personal-data-category.shared.schemas.js';
|
|
49
|
+
import { RedactionType } from '../../compliance/privacy/redaction.shared.schemas.js';
|
|
50
|
+
import { addImpersonalizeWith } from '@wildo-ai/zod-decorators';
|
|
49
51
|
/**
|
|
50
52
|
* Lifecycle of one elevation request.
|
|
51
53
|
*
|
|
@@ -61,10 +63,14 @@ export var PlatformAccessGrantStatus;
|
|
|
61
63
|
/** The tenant refused. Terminal — a new request must be raised rather than this one retried. */
|
|
62
64
|
PlatformAccessGrantStatus["DENIED"] = "denied";
|
|
63
65
|
/**
|
|
64
|
-
* The window elapsed. Terminal, and
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
66
|
+
* The window elapsed. Terminal, and written by the credential-expiry sweep since 2026-09-08
|
|
67
|
+
* (#413) — before that it was reached by NO writer at all, so an elapsed grant read as ACTIVE
|
|
68
|
+
* forever in the customer-facing listing of its own resource.
|
|
69
|
+
*
|
|
70
|
+
* The label is still bookkeeping for humans and reporting, NEVER the control: the admission
|
|
71
|
+
* predicate compares `expiresAt` against now, so an expired grant stops working whether or not
|
|
72
|
+
* the sweep has run. That separation is deliberate and must survive — if admission ever starts
|
|
73
|
+
* reading this label, a lagging sweep becomes an authorization hole rather than a stale display.
|
|
68
74
|
*/
|
|
69
75
|
PlatformAccessGrantStatus["EXPIRED"] = "expired";
|
|
70
76
|
/** Withdrawn before expiry, by the tenant or by the platform. Terminal. */
|
|
@@ -84,6 +90,17 @@ export var PlatformAccessGrantLifecycleTransition;
|
|
|
84
90
|
PlatformAccessGrantLifecycleTransition["APPROVED"] = "approved";
|
|
85
91
|
PlatformAccessGrantLifecycleTransition["DENIED"] = "denied";
|
|
86
92
|
PlatformAccessGrantLifecycleTransition["REVOKED"] = "revoked";
|
|
93
|
+
/**
|
|
94
|
+
* The window elapsed and the sweep relabelled the grant (#413). The ONE transition with no human
|
|
95
|
+
* actor — every other member records a decision somebody made, so an audit row for this one
|
|
96
|
+
* carries no `decidedByUserId`, and that absence is the fact rather than a gap.
|
|
97
|
+
*
|
|
98
|
+
* It is recorded even though the label is bookkeeping and never the control: a customer reading
|
|
99
|
+
* the history of an operator's access to their tenant should see the access END, and a grant that
|
|
100
|
+
* simply stops appearing as ACTIVE with no corresponding row is the version of that history that
|
|
101
|
+
* raises questions.
|
|
102
|
+
*/
|
|
103
|
+
PlatformAccessGrantLifecycleTransition["EXPIRED"] = "expired";
|
|
87
104
|
})(PlatformAccessGrantLifecycleTransition || (PlatformAccessGrantLifecycleTransition = {}));
|
|
88
105
|
/** Why a grant became {@link PlatformAccessGrantStatus.ACTIVE} without a tenant administrator acting. */
|
|
89
106
|
export var PlatformAccessGrantAutoApprovalReason;
|
|
@@ -98,15 +115,33 @@ export var PlatformAccessGrantAutoApprovalReason;
|
|
|
98
115
|
*/
|
|
99
116
|
PlatformAccessGrantAutoApprovalReason["TENANT_CANNOT_APPROVE"] = "tenant_cannot_approve";
|
|
100
117
|
})(PlatformAccessGrantAutoApprovalReason || (PlatformAccessGrantAutoApprovalReason = {}));
|
|
118
|
+
/** Fixed replacement for grant free-text that cannot be cleared (a `.min(1)` field). */
|
|
119
|
+
const ERASED_GRANT_TEXT = '[erased]';
|
|
120
|
+
/**
|
|
121
|
+
* The default life of a grant whose request names no duration.
|
|
122
|
+
*
|
|
123
|
+
* ONE HOUR, and deliberately far below the ceiling. A request that states no duration is the
|
|
124
|
+
* unconsidered case, and the unconsidered case should get the narrowest window that still works —
|
|
125
|
+
* not the widest the system allows. Until 2026-09-08 this was 240, equal to the maximum, so every
|
|
126
|
+
* grant that did not ask was issued a four-hour elevation; that is the opposite of what a
|
|
127
|
+
* just-in-time mechanism is for.
|
|
128
|
+
*
|
|
129
|
+
* Sixty rather than thirty, and the reasoning is the part worth keeping: the failure mode of a
|
|
130
|
+
* too-short default is not a security one, it is that an operator re-requesting mid-incident learns
|
|
131
|
+
* to ask for the maximum every time — which would restore the old behaviour through the front door
|
|
132
|
+
* and make the ceiling the effective default. An hour covers an ordinary support interaction
|
|
133
|
+
* without teaching that habit. An operator who genuinely needs longer asks, and that ask is the
|
|
134
|
+
* record we want.
|
|
135
|
+
*/
|
|
136
|
+
export const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 60;
|
|
101
137
|
/**
|
|
102
|
-
* The maximum life of a grant,
|
|
138
|
+
* The maximum life of a grant, whatever a request asks for.
|
|
103
139
|
*
|
|
104
140
|
* Four hours is a working session, not a working week: long enough that an operator is not
|
|
105
141
|
* re-requesting mid-incident, short enough that a forgotten grant is not a standing privilege by
|
|
106
142
|
* another name. Callers may request LESS; the ceiling is enforced server-side so a client cannot
|
|
107
143
|
* mint a long-lived elevation by asking for one.
|
|
108
144
|
*/
|
|
109
|
-
export const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 240;
|
|
110
145
|
export const PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES = 240;
|
|
111
146
|
/** Statuses from which a grant can still be withdrawn. */
|
|
112
147
|
export const PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES = [
|
|
@@ -135,8 +170,12 @@ export const PlatformAccessGrantSchema = z.object({
|
|
|
135
170
|
// USER_CONTENT — free prose an OPERATOR typed, about why they need to reach a customer tenant.
|
|
136
171
|
// The data subject here is the operator, not the tenant's users; a notice covering staff must
|
|
137
172
|
// enumerate it, and it is exactly the free-text surface that can name a third party in passing.
|
|
138
|
-
|
|
139
|
-
|
|
173
|
+
// MASK on erasure, not REMOVE: `.min(1)` makes this non-clearable, so a null would be rejected by the
|
|
174
|
+
// strict update-DTO parse the impersonalize writer runs. A fixed non-empty string is accepted.
|
|
175
|
+
// It must be scrubbed at all because it is free text an operator wrote about why they needed
|
|
176
|
+
// access — exactly the surface that names a third party in passing.
|
|
177
|
+
justification: addImpersonalizeWith(z.string().min(1).max(1000).isSummaryField()
|
|
178
|
+
.dataCategories(PersonalDataCategory.USER_CONTENT), RedactionType.MASK, { maskValue: ERASED_GRANT_TEXT }),
|
|
140
179
|
status: z.enum(PlatformAccessGrantStatus)
|
|
141
180
|
.systemEnum('PlatformAccessGrantStatus')
|
|
142
181
|
.default(PlatformAccessGrantStatus.PENDING_APPROVAL)
|
|
@@ -169,8 +208,9 @@ export const PlatformAccessGrantSchema = z.object({
|
|
|
169
208
|
.excludeFromUpdate()
|
|
170
209
|
.isAuditEvidence(),
|
|
171
210
|
/** The tenant's reason for refusing, or the revoker's reason for withdrawing. */
|
|
172
|
-
|
|
173
|
-
|
|
211
|
+
// REMOVE — free text again, and clearable (`.optional()`).
|
|
212
|
+
decisionReason: addImpersonalizeWith(z.string().max(1000).optional().excludeFromCreate().excludeFromUpdate()
|
|
213
|
+
.dataCategories(PersonalDataCategory.USER_CONTENT), RedactionType.REMOVE),
|
|
174
214
|
createdAt: z.date().optional(),
|
|
175
215
|
updatedAt: z.date().optional(),
|
|
176
216
|
});
|
|
@@ -235,5 +275,11 @@ export var PlatformAccessGrants_Operations;
|
|
|
235
275
|
PlatformAccessGrants_Operations["APPROVE"] = "approve";
|
|
236
276
|
PlatformAccessGrants_Operations["DENY"] = "deny";
|
|
237
277
|
PlatformAccessGrants_Operations["REVOKE"] = "revoke";
|
|
278
|
+
/**
|
|
279
|
+
* ACTIVE → EXPIRED once the window has elapsed, dispatched by the credential-expiry sweep and by
|
|
280
|
+
* nothing else (#413). Not an operator verb: an operator who wants access to end early uses
|
|
281
|
+
* REVOKE, and nobody needs a button that declares a date has passed.
|
|
282
|
+
*/
|
|
283
|
+
PlatformAccessGrants_Operations["EXPIRE"] = "expire";
|
|
238
284
|
})(PlatformAccessGrants_Operations || (PlatformAccessGrants_Operations = {}));
|
|
239
285
|
//# sourceMappingURL=platform-access-grants.shared.schemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-access-grants.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Platform Access Grants — time-bound, justified, optionally tenant-approved elevation that lets a\n * platform operator cross the tenant boundary.\n *\n * ## Where this sits\n *\n * Wildo's answer to \"may a platform super-administrator administer any tenant?\" is YES, as at most\n * B2B platforms. The question this resource answers is the narrower one that follows: *on what\n * terms?* The progression, recorded in `.claude/rules/administrative-continuity-floors.md`:\n *\n * ambient+unaudited → ambient+audited → declared, deny-by-default → **JIT/time-bound (here)**\n * → customer-approved (here, when the tenant opts in)\n *\n * Declaring a crossing per operation variant (`admitsCrossTenantPlatformAdministration`) removed\n * AMBIENT authority: a crossing must now be asked for in code, reviewed, and specified. It did not\n * remove STANDING authority — every platform administrator still held every declared crossing,\n * permanently, over every tenant. That is the shape zero-standing-privilege programmes exist to\n * eliminate, and what NIST SP 800-53 AC-2 / AC-6(1) mean by least privilege: privileged access is\n * requested, scoped, time-boxed, and expires on its own.\n *\n * A grant is therefore required IN ADDITION to the variant's declaration. The declaration says\n * \"this verb MAY cross\"; the grant says \"this operator MAY cross into THIS tenant, until THIS time,\n * for THIS reason\". Neither is sufficient alone.\n *\n * ## The tenant-approval half (Lockbox)\n *\n * Microsoft Customer Lockbox and Google Access Approval let the CUSTOMER approve provider access\n * before it happens. Wildo models that as {@link PlatformAccessGrantStatus.PENDING_APPROVAL}, gated\n * per tenant so it is an opt-in posture rather than a deployment-wide one — the same shape those\n * products ship, and for the same reason: a tenant that has not staffed an approver must not be\n * unable to receive support.\n *\n * ## ⚠️ The interaction that is easy to get wrong\n *\n * Tenant approval and the administrative-continuity floors are in direct tension. Approval requires\n * an administrator; the floors exist precisely because a tenant can end up WITHOUT one. Requiring a\n * stranded tenant to approve its own repair is circular — the tenant cannot approve, so the repair\n * cannot happen, so the tenant stays stranded.\n *\n * This is resolved by measurement, not by exception: when the target tenant has no administratively\n * usable owner, the grant is auto-approved with\n * {@link PlatformAccessGrantAutoApprovalReason.TENANT_CANNOT_APPROVE} and recorded loudly. The\n * condition is evaluated with the SAME predicate the owner floor uses to refuse writes, so the two\n * can never disagree about whether a tenant can administer itself. An operator cannot manufacture\n * the condition either: stranding a tenant is exactly what the floors refuse.\n */\n\nimport { z } from 'zod';\nimport { PersonalDataCategory } from '../../compliance/privacy/personal-data-category.shared.schemas';\n\n/**\n * Lifecycle of one elevation request.\n *\n * A closed vocabulary with one named runtime source: schemas, guards, fixtures and comparisons all\n * derive from this enum rather than repeating literals.\n */\nexport enum PlatformAccessGrantStatus {\n /** Awaiting a decision from an administrator of the TARGET tenant (Lockbox posture). */\n PENDING_APPROVAL = 'pending_approval',\n /** Usable now. The admission predicate accepts this status, and only while unexpired. */\n ACTIVE = 'active',\n /** The tenant refused. Terminal — a new request must be raised rather than this one retried. */\n DENIED = 'denied',\n /**\n * The window elapsed. Terminal, and reached WITHOUT a writer: the admission predicate compares\n * `expiresAt` against now, so an expired grant stops working whether or not any sweeper has\n * relabelled it. A background transition to this status is bookkeeping for humans and reporting,\n * never the control.\n */\n EXPIRED = 'expired',\n /** Withdrawn before expiry, by the tenant or by the platform. Terminal. */\n REVOKED = 'revoked',\n}\n\n/**\n * Which step of a grant's life an audit row records.\n *\n * Distinct from {@link PlatformAccessGrantStatus}: a status is where the grant IS, a transition is\n * what just happened to it. They differ where it matters — an auto-approved grant lands in `ACTIVE`\n * through `REQUESTED`, never through `APPROVED`, and collapsing the two would erase exactly the\n * distinction a customer audit asks about.\n */\nexport enum PlatformAccessGrantLifecycleTransition {\n REQUESTED = 'requested',\n APPROVED = 'approved',\n DENIED = 'denied',\n REVOKED = 'revoked',\n}\n\n/** Why a grant became {@link PlatformAccessGrantStatus.ACTIVE} without a tenant administrator acting. */\nexport enum PlatformAccessGrantAutoApprovalReason {\n /** The tenant has not opted into approval. The default posture, matching Lockbox being opt-in. */\n TENANT_APPROVAL_NOT_REQUIRED = 'tenant_approval_not_required',\n /**\n * The tenant has NO administratively usable owner, so no principal exists who could approve.\n * Evaluated with the owner floor's own predicate — see this file's header for why the alternative\n * (refusing) is circular. Recorded at high severity: this is the one path where operator access\n * proceeds against a tenant that never consented and never could.\n */\n TENANT_CANNOT_APPROVE = 'tenant_cannot_approve',\n}\n\n/**\n * The maximum life of a grant, and the default when a request names none.\n *\n * Four hours is a working session, not a working week: long enough that an operator is not\n * re-requesting mid-incident, short enough that a forgotten grant is not a standing privilege by\n * another name. Callers may request LESS; the ceiling is enforced server-side so a client cannot\n * mint a long-lived elevation by asking for one.\n */\nexport const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 240;\nexport const PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES = 240;\n\n/** Statuses from which a grant can still be withdrawn. */\nexport const PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES: readonly PlatformAccessGrantStatus[] = [\n PlatformAccessGrantStatus.PENDING_APPROVAL,\n PlatformAccessGrantStatus.ACTIVE,\n];\n\nexport const PlatformAccessGrantSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n\n /**\n * The TARGET tenant — the one being reached into, never the operator's own.\n *\n * This is the scope anchor: the grant is an organization-scoped row so the tenant can see, approve\n * and revoke elevations raised against it. A grant the tenant cannot see would defeat the point of\n * modelling consent at all.\n */\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate().isAuditEvidence(),\n\n /** The operator who requested the elevation. Server-authored from the session, never client-supplied. */\n operatorUserId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n\n /**\n * Why the operator needs access. REQUIRED, and deliberately not optional anywhere in the flow.\n *\n * An elevation record without a reason answers \"who and when\" but not \"why\", which is the only\n * question a reviewer or a customer actually asks. `AC-2(7)` wants privileged assignment monitored;\n * an unexplained monitored assignment is a log line, not a control.\n */\n // USER_CONTENT — free prose an OPERATOR typed, about why they need to reach a customer tenant.\n // The data subject here is the operator, not the tenant's users; a notice covering staff must\n // enumerate it, and it is exactly the free-text surface that can name a third party in passing.\n justification: z.string().min(1).max(1000).isSummaryField()\n .dataCategories(PersonalDataCategory.USER_CONTENT),\n\n status: z.enum(PlatformAccessGrantStatus)\n .systemEnum('PlatformAccessGrantStatus')\n .default(PlatformAccessGrantStatus.PENDING_APPROVAL)\n .isDBIndexed()\n .isSummaryField()\n .excludeFromCreate()\n .excludeFromUpdate()\n .isAuditEvidence(),\n\n /**\n * When the elevation stops working.\n *\n * Server-authored from the requested duration, clamped to\n * {@link PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES}. The admission predicate reads THIS field\n * rather than trusting `status`, so expiry needs no sweeper to take effect.\n */\n expiresAt: z.date().isDBIndexed().isSummaryField().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n\n /** Set when a tenant administrator approved. Absent on an auto-approved grant — see {@link autoApprovalReason}. */\n approvedByUserId: z.string().min(1).optional().isForeignKey().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n approvedAt: z.date().optional().excludeFromCreate().excludeFromUpdate(),\n\n /**\n * Present exactly when the grant became ACTIVE with no tenant administrator acting.\n *\n * Its absence on an ACTIVE grant is therefore meaningful: a human in the tenant approved it. That\n * distinction is what a customer audit needs and what a single `approved: true` boolean would erase.\n */\n autoApprovalReason: z.enum(PlatformAccessGrantAutoApprovalReason)\n .systemEnum('PlatformAccessGrantAutoApprovalReason')\n .optional()\n .excludeFromCreate()\n .excludeFromUpdate()\n .isAuditEvidence(),\n\n /** The tenant's reason for refusing, or the revoker's reason for withdrawing. */\n decisionReason: z.string().max(1000).optional().excludeFromCreate().excludeFromUpdate()\n .dataCategories(PersonalDataCategory.USER_CONTENT),\n\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n});\n\nexport type PlatformAccessGrant = z.infer<typeof PlatformAccessGrantSchema>;\n\n/**\n * Is this grant usable RIGHT NOW?\n *\n * The single predicate every consumer must use — the admission check, the tenant's UI, and any\n * report. Two independent conditions, and the expiry half is why this is a function rather than a\n * status comparison: a grant whose window elapsed is unusable the moment it elapses, with no writer\n * involved. Reading `status === ACTIVE` alone would honour a stale row for as long as no sweeper had\n * run, turning a time-bound elevation back into a standing one.\n *\n * `now` is injected so callers can evaluate a grant at a decision time they already fixed, and so\n * this stays testable without clock control.\n */\nexport function isPlatformAccessGrantUsable(\n grant: Pick<PlatformAccessGrant, 'status' | 'expiresAt'> | undefined,\n now: Date,\n): boolean {\n if (!grant) return false;\n if (grant.status !== PlatformAccessGrantStatus.ACTIVE) return false;\n return grant.expiresAt instanceof Date\n ? grant.expiresAt.getTime() > now.getTime()\n : new Date(grant.expiresAt).getTime() > now.getTime();\n}\n\n/**\n * Clamp a requested duration to the server-side ceiling.\n *\n * Applied to every request path, including trusted ones. A caller asking for a longer window is not\n * refused — being told \"no, ask again with a smaller number\" during an incident is friction with no\n * security benefit, since the ceiling is what actually binds. They simply get the ceiling.\n */\nexport function resolvePlatformAccessGrantExpiry(requestedDurationMinutes: number | undefined, now: Date): Date {\n const requested = requestedDurationMinutes && requestedDurationMinutes > 0\n ? requestedDurationMinutes\n : PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES;\n const minutes = Math.min(requested, PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES);\n return new Date(now.getTime() + minutes * 60_000);\n}\n\n/**\n * NOTE ON PLACEMENT — this enum lives with the VOCABULARY, not with the resource configuration,\n * and moving it back would reintroduce a real defect.\n *\n * The authorization layer needs `REQUEST_ACCESS` by name (it is the bootstrap verb, exempt from the\n * grant requirement it bootstraps). Importing that value from the resources-config module dragged\n * resource-configuration evaluation into the authorizer's module graph, and schema construction that\n * runs before the Zod decorators are initialised loses decorator metadata — which surfaced, far from\n * here, as the ephemeral-disclosure catalogue losing an operation-level declaration. A vocabulary has\n * no such side effects.\n */\n/**\n * Custom verbs. Ordinary CREATE/UPDATE/DELETE are deliberately NOT exposed:\n *\n * - CREATE would let a caller author `status`, `expiresAt` and `operatorUserId` directly, which are\n * precisely the fields whose server authorship IS the control.\n * - UPDATE would be a second, ungated path to the status transitions `approve`/`deny`/`revoke` own.\n * - DELETE exists but has NO client door — see its configuration below. An elevation either side could\n * erase is not evidence; the terminal statuses (DENIED / EXPIRED / REVOKED) are how a grant ends.\n */\nexport enum PlatformAccessGrants_Operations {\n REQUEST_ACCESS = 'requestAccess',\n APPROVE = 'approve',\n DENY = 'deny',\n REVOKE = 'revoke',\n}\n"]}
|
|
1
|
+
{"version":3,"file":"platform-access-grants.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grants.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAC;AACtG,OAAO,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,CAAN,IAAY,yBAoBX;AApBD,WAAY,yBAAyB;IACnC,wFAAwF;IACxF,kEAAqC,CAAA;IACrC,yFAAyF;IACzF,8CAAiB,CAAA;IACjB,gGAAgG;IAChG,8CAAiB,CAAA;IACjB;;;;;;;;;OASG;IACH,gDAAmB,CAAA;IACnB,2EAA2E;IAC3E,gDAAmB,CAAA;AACrB,CAAC,EApBW,yBAAyB,KAAzB,yBAAyB,QAoBpC;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,sCAgBX;AAhBD,WAAY,sCAAsC;IAChD,iEAAuB,CAAA;IACvB,+DAAqB,CAAA;IACrB,2DAAiB,CAAA;IACjB,6DAAmB,CAAA;IACnB;;;;;;;;;OASG;IACH,6DAAmB,CAAA;AACrB,CAAC,EAhBW,sCAAsC,KAAtC,sCAAsC,QAgBjD;AAED,yGAAyG;AACzG,MAAM,CAAN,IAAY,qCAUX;AAVD,WAAY,qCAAqC;IAC/C,kGAAkG;IAClG,sGAA6D,CAAA;IAC7D;;;;;OAKG;IACH,wFAA+C,CAAA;AACjD,CAAC,EAVW,qCAAqC,KAArC,qCAAqC,QAUhD;AAED,wFAAwF;AACxF,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAErC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,8CAA8C,GAAG,EAAE,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8CAA8C,GAAG,GAAG,CAAC;AAElE,0DAA0D;AAC1D,MAAM,CAAC,MAAM,wCAAwC,GAAyC;IAC5F,yBAAyB,CAAC,gBAAgB;IAC1C,yBAAyB,CAAC,MAAM;CACjC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE;IAEtD;;;;;;OAMG;IACH,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE;IAErH,yGAAyG;IACzG,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE;IAEzI;;;;;;OAMG;IACH,+FAA+F;IAC/F,8FAA8F;IAC9F,gGAAgG;IAChG,sGAAsG;IACtG,+FAA+F;IAC/F,6FAA6F;IAC7F,oEAAoE;IACpE,aAAa,EAAE,oBAAoB,CACjC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE;SAC3C,cAAc,CAAC,oBAAoB,CAAC,YAAY,CAAC,EAClD,aAAa,CAAC,IAAI,EAClB,EAAE,SAAS,EAAE,iBAAiB,EAAE,CACjC;IAED,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC;SACtC,UAAU,CAAC,2BAA2B,CAAC;SACvC,OAAO,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;SACnD,WAAW,EAAE;SACb,cAAc,EAAE;SAChB,iBAAiB,EAAE;SACnB,iBAAiB,EAAE;SACnB,eAAe,EAAE;IAEpB;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE;IAE5G,mHAAmH;IACnH,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE;IACvH,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE;IAEvE;;;;;OAKG;IACH,kBAAkB,EAAE,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC;SAC9D,UAAU,CAAC,uCAAuC,CAAC;SACnD,QAAQ,EAAE;SACV,iBAAiB,EAAE;SACnB,iBAAiB,EAAE;SACnB,eAAe,EAAE;IAEpB,iFAAiF;IACjF,2DAA2D;IAC3D,cAAc,EAAE,oBAAoB,CAClC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC,iBAAiB,EAAE;SACtE,cAAc,CAAC,oBAAoB,CAAC,YAAY,CAAC,EAClD,aAAa,CAAC,MAAM,CACrB;IAED,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAIH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAoE,EACpE,GAAS;IAET,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,KAAK,CAAC,MAAM,KAAK,yBAAyB,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACpE,OAAO,KAAK,CAAC,SAAS,YAAY,IAAI;QACpC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;QAC3C,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gCAAgC,CAAC,wBAA4C,EAAE,GAAS;IACtG,MAAM,SAAS,GAAG,wBAAwB,IAAI,wBAAwB,GAAG,CAAC;QACxE,CAAC,CAAC,wBAAwB;QAC1B,CAAC,CAAC,8CAA8C,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,8CAA8C,CAAC,CAAC;IACpF,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,MAAM,CAAN,IAAY,+BAWX;AAXD,WAAY,+BAA+B;IACzC,mEAAgC,CAAA;IAChC,sDAAmB,CAAA;IACnB,gDAAa,CAAA;IACb,oDAAiB,CAAA;IACjB;;;;OAIG;IACH,oDAAiB,CAAA;AACnB,CAAC,EAXW,+BAA+B,KAA/B,+BAA+B,QAW1C","sourcesContent":["/**\n * Platform Access Grants — time-bound, justified, optionally tenant-approved elevation that lets a\n * platform operator cross the tenant boundary.\n *\n * ## Where this sits\n *\n * Wildo's answer to \"may a platform super-administrator administer any tenant?\" is YES, as at most\n * B2B platforms. The question this resource answers is the narrower one that follows: *on what\n * terms?* The progression, recorded in `.claude/rules/administrative-continuity-floors.md`:\n *\n * ambient+unaudited → ambient+audited → declared, deny-by-default → **JIT/time-bound (here)**\n * → customer-approved (here, when the tenant opts in)\n *\n * Declaring a crossing per operation variant (`admitsCrossTenantPlatformAdministration`) removed\n * AMBIENT authority: a crossing must now be asked for in code, reviewed, and specified. It did not\n * remove STANDING authority — every platform administrator still held every declared crossing,\n * permanently, over every tenant. That is the shape zero-standing-privilege programmes exist to\n * eliminate, and what NIST SP 800-53 AC-2 / AC-6(1) mean by least privilege: privileged access is\n * requested, scoped, time-boxed, and expires on its own.\n *\n * A grant is therefore required IN ADDITION to the variant's declaration. The declaration says\n * \"this verb MAY cross\"; the grant says \"this operator MAY cross into THIS tenant, until THIS time,\n * for THIS reason\". Neither is sufficient alone.\n *\n * ## The tenant-approval half (Lockbox)\n *\n * Microsoft Customer Lockbox and Google Access Approval let the CUSTOMER approve provider access\n * before it happens. Wildo models that as {@link PlatformAccessGrantStatus.PENDING_APPROVAL}, gated\n * per tenant so it is an opt-in posture rather than a deployment-wide one — the same shape those\n * products ship, and for the same reason: a tenant that has not staffed an approver must not be\n * unable to receive support.\n *\n * ## ⚠️ The interaction that is easy to get wrong\n *\n * Tenant approval and the administrative-continuity floors are in direct tension. Approval requires\n * an administrator; the floors exist precisely because a tenant can end up WITHOUT one. Requiring a\n * stranded tenant to approve its own repair is circular — the tenant cannot approve, so the repair\n * cannot happen, so the tenant stays stranded.\n *\n * This is resolved by measurement, not by exception: when the target tenant has no administratively\n * usable owner, the grant is auto-approved with\n * {@link PlatformAccessGrantAutoApprovalReason.TENANT_CANNOT_APPROVE} and recorded loudly. The\n * condition is evaluated with the SAME predicate the owner floor uses to refuse writes, so the two\n * can never disagree about whether a tenant can administer itself. An operator cannot manufacture\n * the condition either: stranding a tenant is exactly what the floors refuse.\n */\n\nimport { z } from 'zod';\nimport { PersonalDataCategory } from '../../compliance/privacy/personal-data-category.shared.schemas';\nimport { RedactionType } from '../../compliance/privacy/redaction.shared.schemas';\nimport { addImpersonalizeWith } from '@wildo-ai/zod-decorators';\n\n/**\n * Lifecycle of one elevation request.\n *\n * A closed vocabulary with one named runtime source: schemas, guards, fixtures and comparisons all\n * derive from this enum rather than repeating literals.\n */\nexport enum PlatformAccessGrantStatus {\n /** Awaiting a decision from an administrator of the TARGET tenant (Lockbox posture). */\n PENDING_APPROVAL = 'pending_approval',\n /** Usable now. The admission predicate accepts this status, and only while unexpired. */\n ACTIVE = 'active',\n /** The tenant refused. Terminal — a new request must be raised rather than this one retried. */\n DENIED = 'denied',\n /**\n * The window elapsed. Terminal, and written by the credential-expiry sweep since 2026-09-08\n * (#413) — before that it was reached by NO writer at all, so an elapsed grant read as ACTIVE\n * forever in the customer-facing listing of its own resource.\n *\n * The label is still bookkeeping for humans and reporting, NEVER the control: the admission\n * predicate compares `expiresAt` against now, so an expired grant stops working whether or not\n * the sweep has run. That separation is deliberate and must survive — if admission ever starts\n * reading this label, a lagging sweep becomes an authorization hole rather than a stale display.\n */\n EXPIRED = 'expired',\n /** Withdrawn before expiry, by the tenant or by the platform. Terminal. */\n REVOKED = 'revoked',\n}\n\n/**\n * Which step of a grant's life an audit row records.\n *\n * Distinct from {@link PlatformAccessGrantStatus}: a status is where the grant IS, a transition is\n * what just happened to it. They differ where it matters — an auto-approved grant lands in `ACTIVE`\n * through `REQUESTED`, never through `APPROVED`, and collapsing the two would erase exactly the\n * distinction a customer audit asks about.\n */\nexport enum PlatformAccessGrantLifecycleTransition {\n REQUESTED = 'requested',\n APPROVED = 'approved',\n DENIED = 'denied',\n REVOKED = 'revoked',\n /**\n * The window elapsed and the sweep relabelled the grant (#413). The ONE transition with no human\n * actor — every other member records a decision somebody made, so an audit row for this one\n * carries no `decidedByUserId`, and that absence is the fact rather than a gap.\n *\n * It is recorded even though the label is bookkeeping and never the control: a customer reading\n * the history of an operator's access to their tenant should see the access END, and a grant that\n * simply stops appearing as ACTIVE with no corresponding row is the version of that history that\n * raises questions.\n */\n EXPIRED = 'expired',\n}\n\n/** Why a grant became {@link PlatformAccessGrantStatus.ACTIVE} without a tenant administrator acting. */\nexport enum PlatformAccessGrantAutoApprovalReason {\n /** The tenant has not opted into approval. The default posture, matching Lockbox being opt-in. */\n TENANT_APPROVAL_NOT_REQUIRED = 'tenant_approval_not_required',\n /**\n * The tenant has NO administratively usable owner, so no principal exists who could approve.\n * Evaluated with the owner floor's own predicate — see this file's header for why the alternative\n * (refusing) is circular. Recorded at high severity: this is the one path where operator access\n * proceeds against a tenant that never consented and never could.\n */\n TENANT_CANNOT_APPROVE = 'tenant_cannot_approve',\n}\n\n/** Fixed replacement for grant free-text that cannot be cleared (a `.min(1)` field). */\nconst ERASED_GRANT_TEXT = '[erased]';\n\n/**\n * The default life of a grant whose request names no duration.\n *\n * ONE HOUR, and deliberately far below the ceiling. A request that states no duration is the\n * unconsidered case, and the unconsidered case should get the narrowest window that still works —\n * not the widest the system allows. Until 2026-09-08 this was 240, equal to the maximum, so every\n * grant that did not ask was issued a four-hour elevation; that is the opposite of what a\n * just-in-time mechanism is for.\n *\n * Sixty rather than thirty, and the reasoning is the part worth keeping: the failure mode of a\n * too-short default is not a security one, it is that an operator re-requesting mid-incident learns\n * to ask for the maximum every time — which would restore the old behaviour through the front door\n * and make the ceiling the effective default. An hour covers an ordinary support interaction\n * without teaching that habit. An operator who genuinely needs longer asks, and that ask is the\n * record we want.\n */\nexport const PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES = 60;\n\n/**\n * The maximum life of a grant, whatever a request asks for.\n *\n * Four hours is a working session, not a working week: long enough that an operator is not\n * re-requesting mid-incident, short enough that a forgotten grant is not a standing privilege by\n * another name. Callers may request LESS; the ceiling is enforced server-side so a client cannot\n * mint a long-lived elevation by asking for one.\n */\nexport const PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES = 240;\n\n/** Statuses from which a grant can still be withdrawn. */\nexport const PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES: readonly PlatformAccessGrantStatus[] = [\n PlatformAccessGrantStatus.PENDING_APPROVAL,\n PlatformAccessGrantStatus.ACTIVE,\n];\n\nexport const PlatformAccessGrantSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n\n /**\n * The TARGET tenant — the one being reached into, never the operator's own.\n *\n * This is the scope anchor: the grant is an organization-scoped row so the tenant can see, approve\n * and revoke elevations raised against it. A grant the tenant cannot see would defeat the point of\n * modelling consent at all.\n */\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate().isAuditEvidence(),\n\n /** The operator who requested the elevation. Server-authored from the session, never client-supplied. */\n operatorUserId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n\n /**\n * Why the operator needs access. REQUIRED, and deliberately not optional anywhere in the flow.\n *\n * An elevation record without a reason answers \"who and when\" but not \"why\", which is the only\n * question a reviewer or a customer actually asks. `AC-2(7)` wants privileged assignment monitored;\n * an unexplained monitored assignment is a log line, not a control.\n */\n // USER_CONTENT — free prose an OPERATOR typed, about why they need to reach a customer tenant.\n // The data subject here is the operator, not the tenant's users; a notice covering staff must\n // enumerate it, and it is exactly the free-text surface that can name a third party in passing.\n // MASK on erasure, not REMOVE: `.min(1)` makes this non-clearable, so a null would be rejected by the\n // strict update-DTO parse the impersonalize writer runs. A fixed non-empty string is accepted.\n // It must be scrubbed at all because it is free text an operator wrote about why they needed\n // access — exactly the surface that names a third party in passing.\n justification: addImpersonalizeWith(\n z.string().min(1).max(1000).isSummaryField()\n .dataCategories(PersonalDataCategory.USER_CONTENT),\n RedactionType.MASK,\n { maskValue: ERASED_GRANT_TEXT },\n ),\n\n status: z.enum(PlatformAccessGrantStatus)\n .systemEnum('PlatformAccessGrantStatus')\n .default(PlatformAccessGrantStatus.PENDING_APPROVAL)\n .isDBIndexed()\n .isSummaryField()\n .excludeFromCreate()\n .excludeFromUpdate()\n .isAuditEvidence(),\n\n /**\n * When the elevation stops working.\n *\n * Server-authored from the requested duration, clamped to\n * {@link PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES}. The admission predicate reads THIS field\n * rather than trusting `status`, so expiry needs no sweeper to take effect.\n */\n expiresAt: z.date().isDBIndexed().isSummaryField().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n\n /** Set when a tenant administrator approved. Absent on an auto-approved grant — see {@link autoApprovalReason}. */\n approvedByUserId: z.string().min(1).optional().isForeignKey().excludeFromCreate().excludeFromUpdate().isAuditEvidence(),\n approvedAt: z.date().optional().excludeFromCreate().excludeFromUpdate(),\n\n /**\n * Present exactly when the grant became ACTIVE with no tenant administrator acting.\n *\n * Its absence on an ACTIVE grant is therefore meaningful: a human in the tenant approved it. That\n * distinction is what a customer audit needs and what a single `approved: true` boolean would erase.\n */\n autoApprovalReason: z.enum(PlatformAccessGrantAutoApprovalReason)\n .systemEnum('PlatformAccessGrantAutoApprovalReason')\n .optional()\n .excludeFromCreate()\n .excludeFromUpdate()\n .isAuditEvidence(),\n\n /** The tenant's reason for refusing, or the revoker's reason for withdrawing. */\n // REMOVE — free text again, and clearable (`.optional()`).\n decisionReason: addImpersonalizeWith(\n z.string().max(1000).optional().excludeFromCreate().excludeFromUpdate()\n .dataCategories(PersonalDataCategory.USER_CONTENT),\n RedactionType.REMOVE,\n ),\n\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n});\n\nexport type PlatformAccessGrant = z.infer<typeof PlatformAccessGrantSchema>;\n\n/**\n * Is this grant usable RIGHT NOW?\n *\n * The single predicate every consumer must use — the admission check, the tenant's UI, and any\n * report. Two independent conditions, and the expiry half is why this is a function rather than a\n * status comparison: a grant whose window elapsed is unusable the moment it elapses, with no writer\n * involved. Reading `status === ACTIVE` alone would honour a stale row for as long as no sweeper had\n * run, turning a time-bound elevation back into a standing one.\n *\n * `now` is injected so callers can evaluate a grant at a decision time they already fixed, and so\n * this stays testable without clock control.\n */\nexport function isPlatformAccessGrantUsable(\n grant: Pick<PlatformAccessGrant, 'status' | 'expiresAt'> | undefined,\n now: Date,\n): boolean {\n if (!grant) return false;\n if (grant.status !== PlatformAccessGrantStatus.ACTIVE) return false;\n return grant.expiresAt instanceof Date\n ? grant.expiresAt.getTime() > now.getTime()\n : new Date(grant.expiresAt).getTime() > now.getTime();\n}\n\n/**\n * Clamp a requested duration to the server-side ceiling.\n *\n * Applied to every request path, including trusted ones. A caller asking for a longer window is not\n * refused — being told \"no, ask again with a smaller number\" during an incident is friction with no\n * security benefit, since the ceiling is what actually binds. They simply get the ceiling.\n */\nexport function resolvePlatformAccessGrantExpiry(requestedDurationMinutes: number | undefined, now: Date): Date {\n const requested = requestedDurationMinutes && requestedDurationMinutes > 0\n ? requestedDurationMinutes\n : PLATFORM_ACCESS_GRANT_DEFAULT_DURATION_MINUTES;\n const minutes = Math.min(requested, PLATFORM_ACCESS_GRANT_MAXIMUM_DURATION_MINUTES);\n return new Date(now.getTime() + minutes * 60_000);\n}\n\n/**\n * NOTE ON PLACEMENT — this enum lives with the VOCABULARY, not with the resource configuration,\n * and moving it back would reintroduce a real defect.\n *\n * The authorization layer needs `REQUEST_ACCESS` by name (it is the bootstrap verb, exempt from the\n * grant requirement it bootstraps). Importing that value from the resources-config module dragged\n * resource-configuration evaluation into the authorizer's module graph, and schema construction that\n * runs before the Zod decorators are initialised loses decorator metadata — which surfaced, far from\n * here, as the ephemeral-disclosure catalogue losing an operation-level declaration. A vocabulary has\n * no such side effects.\n */\n/**\n * Custom verbs. Ordinary CREATE/UPDATE/DELETE are deliberately NOT exposed:\n *\n * - CREATE would let a caller author `status`, `expiresAt` and `operatorUserId` directly, which are\n * precisely the fields whose server authorship IS the control.\n * - UPDATE would be a second, ungated path to the status transitions `approve`/`deny`/`revoke` own.\n * - DELETE exists but has NO client door — see its configuration below. An elevation either side could\n * erase is not evidence; the terminal statuses (DENIED / EXPIRED / REVOKED) are how a grant ends.\n */\nexport enum PlatformAccessGrants_Operations {\n REQUEST_ACCESS = 'requestAccess',\n APPROVE = 'approve',\n DENY = 'deny',\n REVOKE = 'revoke',\n /**\n * ACTIVE → EXPIRED once the window has elapsed, dispatched by the credential-expiry sweep and by\n * nothing else (#413). Not an operator verb: an operator who wants access to end early uses\n * REVOKE, and nobody needs a button that declares a date has passed.\n */\n EXPIRE = 'expire',\n}\n"]}
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ResourcePrimaryScope } from '../../resources/resources.shared.schemas';
|
|
3
3
|
export declare enum CORE_APP_ROLES {
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Open access: an operation declaring `APP_PUBLIC` requires NO credential, and imposes no role
|
|
6
|
+
* requirement on one that is presented.
|
|
7
|
+
*
|
|
8
|
+
* Not a role anybody is granted — a SENTINEL on the operation's `roles`, which is why the two
|
|
9
|
+
* halves above have to be stated together. "Accessible without auth" was the whole comment until
|
|
10
|
+
* 2026-08-31, and it was read as *reachable only when unauthenticated*: every role gate then
|
|
11
|
+
* refused a credentialed caller, so a public price list, catalogue or i18n bundle answered 200 to
|
|
12
|
+
* an anonymous probe and 403 to a logged-in customer (#153). Authenticating must never take access
|
|
13
|
+
* away.
|
|
14
|
+
*
|
|
15
|
+
* `requiredRolesDeclarePublicAccess` in `roles.shared.utils.ts` is the runtime source of this
|
|
16
|
+
* meaning; every gate consults it rather than re-deriving the test. Scope, tenancy and the
|
|
17
|
+
* repository's contextual filter are untouched by the declaration — it says no role is required to
|
|
18
|
+
* ASK, never that no scope confines the answer.
|
|
19
|
+
*/
|
|
5
20
|
APP_PUBLIC = "APP_PUBLIC",
|
|
6
21
|
APP_ADMIN_SUPER_ADMIN = "APP_ADMIN_SUPER_ADMIN",
|
|
7
22
|
APP_ADMIN_BILLING_MANAGER = "APP_ADMIN_BILLING_MANAGER",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/roles.shared.schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,oBAAY,cAAc;IACxB
|
|
1
|
+
{"version":3,"file":"roles.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/roles.shared.schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,oBAAY,cAAc;IACxB;;;;;;;;;;;;;;;OAeG;IACH,UAAU,eAAe;IACzB,qBAAqB,0BAA0B;IAC/C,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IACzD,gBAAgB,qBAAqB;IACrC,QAAQ,aAAa;IACrB,iGAAiG;IACjG,aAAa,kBAAkB;CAChC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qCAAqC,EAAE,SAAS,cAAc,EAKzE,CAAC;AAEH,oBAAY,cAAc;IACxB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,UAAU,eAAe;CAC1B;AAGD,eAAO,MAAM,eAAe,2FAG1B,CAAC;AAEH,eAAO,MAAM,WAAW,wGAItB,CAAC;AAEH,eAAO,MAAM,cAAc,sEAGzB,CAAC;AAEH,eAAO,MAAM,cAAc,sEAGzB,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;iBAK/B,CAAC;AAGH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,wBAAwB;;;;;kBAYpC,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -2,7 +2,22 @@ import { z } from 'zod';
|
|
|
2
2
|
import { ResourcePrimaryScope } from '../../resources/resources.shared.schemas.js';
|
|
3
3
|
export var CORE_APP_ROLES;
|
|
4
4
|
(function (CORE_APP_ROLES) {
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Open access: an operation declaring `APP_PUBLIC` requires NO credential, and imposes no role
|
|
7
|
+
* requirement on one that is presented.
|
|
8
|
+
*
|
|
9
|
+
* Not a role anybody is granted — a SENTINEL on the operation's `roles`, which is why the two
|
|
10
|
+
* halves above have to be stated together. "Accessible without auth" was the whole comment until
|
|
11
|
+
* 2026-08-31, and it was read as *reachable only when unauthenticated*: every role gate then
|
|
12
|
+
* refused a credentialed caller, so a public price list, catalogue or i18n bundle answered 200 to
|
|
13
|
+
* an anonymous probe and 403 to a logged-in customer (#153). Authenticating must never take access
|
|
14
|
+
* away.
|
|
15
|
+
*
|
|
16
|
+
* `requiredRolesDeclarePublicAccess` in `roles.shared.utils.ts` is the runtime source of this
|
|
17
|
+
* meaning; every gate consults it rather than re-deriving the test. Scope, tenancy and the
|
|
18
|
+
* repository's contextual filter are untouched by the declaration — it says no role is required to
|
|
19
|
+
* ASK, never that no scope confines the answer.
|
|
20
|
+
*/
|
|
6
21
|
CORE_APP_ROLES["APP_PUBLIC"] = "APP_PUBLIC";
|
|
7
22
|
CORE_APP_ROLES["APP_ADMIN_SUPER_ADMIN"] = "APP_ADMIN_SUPER_ADMIN";
|
|
8
23
|
CORE_APP_ROLES["APP_ADMIN_BILLING_MANAGER"] = "APP_ADMIN_BILLING_MANAGER";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/roles.shared.schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"roles.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/roles.shared.schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,MAAM,CAAN,IAAY,cAyBX;AAzBD,WAAY,cAAc;IACxB;;;;;;;;;;;;;;;OAeG;IACH,2CAAyB,CAAA;IACzB,iEAA+C,CAAA;IAC/C,yEAAuD,CAAA;IACvD,2EAAyD,CAAA;IACzD,uDAAqC,CAAA;IACrC,uCAAqB,CAAA;IACrB,iGAAiG;IACjG,iDAA+B,CAAA;AACjC,CAAC,EAzBW,cAAc,KAAd,cAAc,QAyBzB;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAA8B,MAAM,CAAC,MAAM,CAAC;IAC5F,cAAc,CAAC,qBAAqB;IACpC,cAAc,CAAC,yBAAyB;IACxC,cAAc,CAAC,0BAA0B;IACzC,cAAc,CAAC,gBAAgB;CAChC,CAAC,CAAC;AAEH,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACxB,yCAAuB,CAAA;IACvB,yCAAuB,CAAA;IACvB,yCAAuB,CAAA;IACvB,6CAA2B,CAAA;IAC3B,2CAAyB,CAAA;AAC3B,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB;AAGD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC;IACrC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IACtB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC;IACjC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IACtB,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IACtB,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IACtB,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;IACtB,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE;IACnC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACxC,mBAAmB,EAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;CACnD,CAAC,CAAC;AAKH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,MAAM,CACvF,CAAC,MAAM,EAAE,EAAE;IACT,yCAAyC;IACzC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QACrC,IAAI,CAAC;YACH,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CACF,CAAC","sourcesContent":["\nimport { z } from 'zod';\nimport { ResourcePrimaryScope } from '../../resources/resources.shared.schemas';\n\nexport enum CORE_APP_ROLES {\n /**\n * Open access: an operation declaring `APP_PUBLIC` requires NO credential, and imposes no role\n * requirement on one that is presented.\n *\n * Not a role anybody is granted — a SENTINEL on the operation's `roles`, which is why the two\n * halves above have to be stated together. \"Accessible without auth\" was the whole comment until\n * 2026-08-31, and it was read as *reachable only when unauthenticated*: every role gate then\n * refused a credentialed caller, so a public price list, catalogue or i18n bundle answered 200 to\n * an anonymous probe and 403 to a logged-in customer (#153). Authenticating must never take access\n * away.\n *\n * `requiredRolesDeclarePublicAccess` in `roles.shared.utils.ts` is the runtime source of this\n * meaning; every gate consults it rather than re-deriving the test. Scope, tenancy and the\n * repository's contextual filter are untouched by the declaration — it says no role is required to\n * ASK, never that no scope confines the answer.\n */\n APP_PUBLIC = 'APP_PUBLIC',\n APP_ADMIN_SUPER_ADMIN = 'APP_ADMIN_SUPER_ADMIN',\n APP_ADMIN_BILLING_MANAGER = 'APP_ADMIN_BILLING_MANAGER',\n APP_ADMIN_MARKETING_EDITOR = 'APP_ADMIN_MARKETING_EDITOR',\n APP_ADMIN_VIEWER = 'APP_ADMIN_VIEWER',\n APP_USER = 'APP_USER',\n /** Anonymous session access. Operations with APP_ANONYMOUS are accessible to anonymous users. */\n APP_ANONYMOUS = 'APP_ANONYMOUS',\n}\n\n/**\n * Authorities that administer the generated application itself.\n *\n * This named subset is the canonical boundary used by consumer-facing\n * products such as the API reference. It prevents each downstream consumer\n * from guessing administrative meaning from `APP_ADMIN_` spelling or copying\n * an independent list that drifts when the role vocabulary evolves.\n */\nexport const CORE_APPLICATION_ADMINISTRATION_ROLES: readonly CORE_APP_ROLES[] = Object.freeze([\n CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN,\n CORE_APP_ROLES.APP_ADMIN_BILLING_MANAGER,\n CORE_APP_ROLES.APP_ADMIN_MARKETING_EDITOR,\n CORE_APP_ROLES.APP_ADMIN_VIEWER,\n]);\n\nexport enum CORE_ORG_ROLES {\n ORG_GUEST = 'ORG_GUEST',\n ORG_OWNER = 'ORG_OWNER',\n ORG_ADMIN = 'ORG_ADMIN',\n ORG_MANAGER = 'ORG_MANAGER',\n ORG_MEMBER = 'ORG_MEMBER',\n}\n\n\nexport const CoreRolesSchema = z.union([\n z.enum(CORE_APP_ROLES),\n z.enum(CORE_ORG_ROLES),\n]);\n\nexport const RolesSchema = z.union([\n z.enum(CORE_APP_ROLES),\n z.enum(CORE_ORG_ROLES),\n z.string().min(1),\n]);\n\nexport const AppRolesSchema = z.union([\n z.enum(CORE_APP_ROLES),\n z.string().min(1),\n]);\n\nexport const OrgRolesSchema = z.union([\n z.enum(CORE_ORG_ROLES),\n z.string().min(1),\n]);\n\nexport const RoleDefinitionSchema = z.object({\n role: RolesSchema,\n inheritFrom: RolesSchema.optional(),\n isSystemRole: z.boolean().default(false),\n relatedPrimaryScope : z.enum(ResourcePrimaryScope),\n});\n\n\nexport type RoleDefinition = z.infer<typeof RoleDefinitionSchema>;\n\nexport const RolesConfigurationSchema = z.record(z.string(), RoleDefinitionSchema).refine(\n (record) => {\n // Validate that all keys are valid roles\n return Object.keys(record).every(key => {\n try {\n RolesSchema.parse(key);\n return true;\n } catch {\n return false;\n }\n });\n }\n);\n\nexport type Roles = z.infer<typeof RolesSchema>;\nexport type CoreRoles = z.infer<typeof CoreRolesSchema>;\nexport type AppRoles = z.infer<typeof AppRolesSchema>;\nexport type OrgRoles = z.infer<typeof OrgRolesSchema>;\nexport type RolesConfiguration = z.infer<typeof RolesConfigurationSchema>;\n"]}
|