---
id: ATS-PFM-SEC-013
scope: CAP-PFM-SEC-013
product_area: platform
module: security
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
scenarios:
  - id: ATS-PFM-SEC-013-01
    title: Reconciliation ownership and repeatability
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-01
    preconditions: Prepare Platform and CRM release declarations.
    steps: Reconcile CRM and then repeat an unchanged Platform release.
    expected: 'CRM does not change Platform-owned definitions, and the repeat causes no version increases.'
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#leaves
        another service's keys and built-ins alone: CRM going live does not undo Platform
      - TST-PFM-SEC-095
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#run
        again with the same catalog changes nothing, which is what a redeploy is
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#changes
        nothing when the catalog is the one already stored, and bumps no version
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#leaves
      another service's keys and built-ins alone: CRM going live does not undo Platform
    category: invariant
    test_references:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#leaves
        another service's keys and built-ins alone: CRM going live does not undo Platform
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#run
        again with the same catalog changes nothing, which is what a redeploy is
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#changes
        nothing when the catalog is the one already stored, and bumps no version
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#leaves
        another service's keys and built-ins alone: CRM going live does not undo Platform
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#leaves
        another service's keys and built-ins alone: CRM going live does not undo Platform
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-02
    title: Policy tier membership
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-02
    preconditions: Prepare eligible keys from each tier.
    steps: Generate the application policies.
    expected: >-
      Read Only has read keys, User includes read/user keys and Administrator includes all eligible
      tiers as exact allows.
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the read-only policy the app’s read keys and nothing above them
      - TST-PFM-SEC-202
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the user policy the read and user keys
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the administrator policy every key of its app
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#writes
        each tier policy as one allow of exact keys, and no deny
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
      the read-only policy the app’s read keys and nothing above them
    category: rule
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the read-only policy the app’s read keys and nothing above them
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the user policy the read and user keys
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the administrator policy every key of its app
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#writes
        each tier policy as one allow of exact keys, and no deny
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the read-only policy the app’s read keys and nothing above them
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        the read-only policy the app’s read keys and nothing above them
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-03
    title: Excluded powers in generated policies
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-03
    preconditions: Use the Platform catalog.
    steps: Generate its tier policies.
    expected: >-
      Generated policies omit staff-only, self-read, security-administration, staff-access and
      export permissions.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a staff-only key out of its app’s administrator policy
      - TST-PFM-SEC-202
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        the self-access key out of every tier, because the grant resolver answers it from the user’s
        own row
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a security power out of the Platform administrator policy, so a Power User cannot grant
        themselves more
      - >-
        services-platform:modules/security/tests/unit/services/catalog/staff-access-authority.spec.ts#generates
        neither into any tier policy of Platform
      - TST-PFM-SEC-203
      - >-
        services-platform:modules/security/tests/unit/services/catalog/export-authority.spec.ts#generates
        none of them into any tier policy of Platform
      - TST-PFM-SEC-201
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
      a staff-only key out of its app’s administrator policy
    category: boundary
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a staff-only key out of its app’s administrator policy
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        the self-access key out of every tier, because the grant resolver answers it from the user’s
        own row
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a security power out of the Platform administrator policy, so a Power User cannot grant
        themselves more
      - >-
        services-platform:modules/security/tests/unit/services/catalog/staff-access-authority.spec.ts#generates
        neither into any tier policy of Platform
      - >-
        services-platform:modules/security/tests/unit/services/catalog/export-authority.spec.ts#generates
        none of them into any tier policy of Platform
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a staff-only key out of its app’s administrator policy
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#keeps
        a staff-only key out of its app’s administrator policy
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-04
    title: Declared built-in validation before storage
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-04
    preconditions: 'Prepare foreign-application, unknown-key, allow-pattern and reserved-name declarations.'
    steps: Attempt reconciliation with each invalid declaration.
    expected: Each fails and writes no built-in definition.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#refuses
        it, naming the policy and the app this service defines no permission for
      - TST-PFM-SEC-096
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a declaration that allows a key the release does not define, writing nothing
      - TST-PFM-SEC-095
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a declaration whose allow is a pattern, writing nothing
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a declaration taking a key the tier generator owns
      - TST-PFM-SEC-200
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#refuses
      it, naming the policy and the app this service defines no permission for
    category: validation
    test_references:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#refuses
        it, naming the policy and the app this service defines no permission for
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a declaration that allows a key the release does not define, writing nothing
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a declaration whose allow is a pattern, writing nothing
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a declaration taking a key the tier generator owns
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#refuses
        it, naming the policy and the app this service defines no permission for
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#refuses
        it, naming the policy and the app this service defines no permission for
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-05
    title: Shared built-in creation and updates
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-05
      - INV-DOM-PFM-SEC-003-16
    preconditions: Prepare two customer views of the catalog.
    steps: Publish a declared built-in and update its rules.
    expected: It initially has no role holder; both customer views refer to the same updated definition.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
        a newly shipped built-in to nobody: no role references it
      - TST-PFM-SEC-095
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#is
        one row two customers share, and a rule change reaches both without copying anything
      - >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#grants
        the new built-in to nobody: no built-in role picks a declaration up
      - TST-PFM-SEC-096
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
      a newly shipped built-in to nobody: no role references it
    category: transition
    test_references:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
        a newly shipped built-in to nobody: no role references it
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#is
        one row two customers share, and a rule change reaches both without copying anything
      - >-
        services-platform:modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js#grants
        the new built-in to nobody: no built-in role picks a declaration up
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
        a newly shipped built-in to nobody: no role references it
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
        a newly shipped built-in to nobody: no role references it
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-06
    title: 'Built-in rename, withdrawal and restoration'
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-06
    preconditions: Prepare a referenced built-in.
    steps: 'Rename through former keys, withdraw it from a release and publish it again.'
    expected: >-
      Identity and references survive rename, withdrawal archives authority with recorded holders,
      and restoration reuses the original row.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#renames
        a key through formerKeys, keeping the row and every reference to it
      - TST-PFM-SEC-095
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#archives
        a built-in the release no longer declares and audits the roles still holding it
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#makes
        a retired built-in grant nothing while its holder keeps every other grant
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#brings
        a built-in back on its own row when a later release ships it again
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#renames
      a key through formerKeys, keeping the row and every reference to it
    category: transition
    test_references:
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#renames
        a key through formerKeys, keeping the row and every reference to it
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#archives
        a built-in the release no longer declares and audits the roles still holding it
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#makes
        a retired built-in grant nothing while its holder keeps every other grant
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#brings
        a built-in back on its own row when a later release ships it again
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#renames
        a key through formerKeys, keeping the row and every reference to it
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#renames
        a key through formerKeys, keeping the row and every reference to it
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-07
    title: The shipped role composition
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-07
    preconditions: Use Platform’s reconciled catalog.
    steps: Build its standard roles.
    expected: >-
      Eight roles are produced; the customer Administrator carries the security-administrator and
      data-exporter policies and Power User does not.
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#publishes
        the eight roles the catalog ships, in the order it ships them
      - TST-PFM-SEC-202
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        Power User the administrator policies without the security administrator
      - >-
        services-platform:modules/security/tests/unit/services/catalog/export-authority.spec.ts#attaches
        it to no other built-in role, Power User included
      - TST-PFM-SEC-201
      - >-
        services-platform:modules/security/tests/integration/services/catalog/staff-access-authority.integration.spec.js#leaves
        no policy of the Power User role allowing either staff access key
      - TST-PFM-SEC-097
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#publishes
      the eight roles the catalog ships, in the order it ships them
    category: rule
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#publishes
        the eight roles the catalog ships, in the order it ships them
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        Power User the administrator policies without the security administrator
      - >-
        services-platform:modules/security/tests/unit/services/catalog/export-authority.spec.ts#attaches
        it to no other built-in role, Power User included
      - >-
        services-platform:modules/security/tests/integration/services/catalog/staff-access-authority.integration.spec.js#leaves
        no policy of the Power User role allowing either staff access key
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#publishes
        the eight roles the catalog ships, in the order it ships them
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#publishes
        the eight roles the catalog ships, in the order it ships them
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-08
    title: Built-in patterns and emergency authority
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-09
    preconditions: Prepare the built-in role declarations.
    steps: Match their patterns against the relevant customer custom-record keys.
    expected: >-
      No tested pattern reaches those custom records, and emergency authority is confined to Rhythm
      Administrator.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        no built-in role a pattern that reaches a customer’s own records, the staff roles included
      - TST-PFM-SEC-202
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        hq.emergency-access.use to Rhythm Administrator alone: Support Representative and Software
        Engineer are refused it
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        every customer-scope role the customer’s own scope, so none of them reaches the platform
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
      no built-in role a pattern that reaches a customer’s own records, the staff roles included
    category: permission
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        no built-in role a pattern that reaches a customer’s own records, the staff roles included
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        hq.emergency-access.use to Rhythm Administrator alone: Support Representative and Software
        Engineer are refused it
      - >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        every customer-scope role the customer’s own scope, so none of them reaches the platform
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        no built-in role a pattern that reaches a customer’s own records, the staff roles included
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts#gives
        no built-in role a pattern that reaches a customer’s own records, the staff roles included
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-09
    title: The database reconciliation boundary
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-10
      - INV-DOM-PFM-SEC-003-13
    preconditions: 'Prepare built-in role, policy, rule and attachment rows.'
    steps: Attempt mutations outside and within reconciliation.
    expected: >-
      Built-in mutations fail outside reconciliation and succeed through it; custom rows retain
      their separate behavior.
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an insert, an update and a delete of a built-in role outside a reconciliation
      - TST-PFM-SEC-074
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        a rule of a built-in outside a reconciliation, and allows the same rule inside one
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an attachment on a built-in role outside a reconciliation: what a built-in is made of is
        Rhythm's
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#leaves
        a customer's own policy alone: the window is about Rhythm's rows, not about the table
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
      an insert, an update and a delete of a built-in role outside a reconciliation
    category: invariant
    test_references:
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an insert, an update and a delete of a built-in role outside a reconciliation
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        a rule of a built-in outside a reconciliation, and allows the same rule inside one
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an attachment on a built-in role outside a reconciliation: what a built-in is made of is
        Rhythm's
      - >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#leaves
        a customer's own policy alone: the window is about Rhythm's rows, not about the table
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an insert, an update and a delete of a built-in role outside a reconciliation
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
        an insert, an update and a delete of a built-in role outside a reconciliation
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-10
    title: Malformed and altered published releases
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-11
    preconditions: 'Prepare duplicate keys, malformed keys and an altered checksum for an existing release.'
    steps: Run release validation.
    expected: 'Problems are reported together, no invalid writes occur and changed republication is refused.'
    negative: true
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key defined twice, naming the key so the release is fixed rather than hunted for
      - TST-PFM-SEC-200
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key that is not <app>.<resource>.<action>, before a row carries it
      - >-
        services-platform:modules/security/tests/unit/authorizer/registry-publish.spec.ts#refuses a
        release already published with another checksum: a release is immutable
      - TST-PFM-SEC-197
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a release with no identifier, a key defined twice and a malformed key, writing nothing
      - TST-PFM-SEC-095
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses a
      key defined twice, naming the key so the release is fixed rather than hunted for
    category: validation
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key defined twice, naming the key so the release is fixed rather than hunted for
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key that is not <app>.<resource>.<action>, before a row carries it
      - >-
        services-platform:modules/security/tests/unit/authorizer/registry-publish.spec.ts#refuses a
        release already published with another checksum: a release is immutable
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#refuses
        a release with no identifier, a key defined twice and a malformed key, writing nothing
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key defined twice, naming the key so the release is fixed rather than hunted for
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#refuses
        a key defined twice, naming the key so the release is fixed rather than hunted for
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-11
    title: Shared permission-pattern results
    level: unit
    proves:
      - BR-CAP-PFM-SEC-013-12
    preconditions: Prepare the permission and pattern corpus.
    steps: Compare the four matcher entry points.
    expected: 'All entry points agree, including supported short patterns spanning remaining segments.'
    negative: false
    data_needs: Use the records described in the setup.
    bound_to:
      - >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#gives
        the same answer from all four functions for every pattern and key of the corpus
      - TST-PFM-SEC-214
      - >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#matches
        hq.roles.manage from the pattern hq.*, the rule the grant slice used to drop
    provenance: test
    source: >-
      services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#gives
      the same answer from all four functions for every pattern and key of the corpus
    category: interaction
    test_references:
      - >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#gives
        the same answer from all four functions for every pattern and key of the corpus
      - >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#matches
        hq.roles.manage from the pattern hq.*, the rule the grant slice used to drop
    action_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#gives
        the same answer from all four functions for every pattern and key of the corpus
    assertion_evidence:
      provenance: test
      source: >-
        services-platform:modules/security/tests/unit/services/persistence/permission-matcher.spec.ts#gives
        the same answer from all four functions for every pattern and key of the corpus
    binding_scope: >-
      The binding applies to the cited executable observations and their dependency boundary. Extra
      setup, operations or combinations in this scenario still require evidence before the whole
      scenario is qualified.
  - id: ATS-PFM-SEC-013-12
    title: 'Custom and built-in access definition: active to archived'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-06
    state_model: STATE-PFM-SEC-008
    transition:
      from: active
      to: archived
      index: 1
    preconditions: >-
      Prepare a run-owned custom and built-in access definition in active state with the authority
      and inputs required by the cited transition.
    steps:
      - do: Publish a release omitting the built-in and inspect holders and impact history.
        expect: >-
          After the stated action, observe the custom and built-in access definition in archived
          state. This case does not require an additional history event unless the transition
          explicitly defines one.
        provenance: proposed
        source:
          - >-
            services-platform:modules/security/services/catalog/reconcile-catalog.ts:reconcileCatalog
          - >-
            services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
            security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
            impact.ts; services/catalog/*.
    expected: >-
      After the stated action, observe the custom and built-in access definition in archived state.
      This case does not require an additional history event unless the transition explicitly
      defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/security/services/catalog/reconcile-catalog.ts:reconcileCatalog'
      - >-
        services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
        security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
        impact.ts; services/catalog/*.
    guard_cases: Only release reconciliation may change the built-in.
    side_effects_to_verify:
      - Withdraw its authority and record affected holders
    transition_assertion:
      state: archived
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/reconcile-catalog.ts:reconcileCatalog'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/reconcile-catalog.ts:reconcileCatalog'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/reconcile-catalog.ts:reconcileCatalog'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-013-13
    title: 'Custom and built-in access definition: archived to active'
    category: transition
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-06
    state_model: STATE-PFM-SEC-008
    transition:
      from: archived
      to: active
      index: 2
    preconditions: >-
      Prepare a run-owned custom and built-in access definition in archived state with the authority
      and inputs required by the cited transition.
    steps:
      - do: Publish a later release that declares the archived built-in again.
        expect: >-
          After the stated action, observe the custom and built-in access definition in active
          state. This case does not require an additional history event unless the transition
          explicitly defines one.
        provenance: proposed
        source:
          - 'services-platform:modules/security/services/catalog/catalog-plan.ts:planBuiltInPolicy'
          - >-
            services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
            security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
            impact.ts; services/catalog/*.
    expected: >-
      After the stated action, observe the custom and built-in access definition in active state.
      This case does not require an additional history event unless the transition explicitly
      defines one.
    negative: false
    data_needs: >-
      A disposable customer, workspace and named actor; a controllable clock where the transition
      depends on time.
    bound_to: []
    provenance: proposed
    source:
      - 'services-platform:modules/security/services/catalog/catalog-plan.ts:planBuiltInPolicy'
      - >-
        services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
        security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
        impact.ts; services/catalog/*.
    guard_cases: Only release reconciliation may restore it.
    side_effects_to_verify:
      - Reuse the built-in identity and references
    transition_assertion:
      state: active
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/catalog-plan.ts:planBuiltInPolicy'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    action_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/catalog-plan.ts:planBuiltInPolicy'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    assertion_evidence:
      provenance: proposed
      source:
        - 'services-platform:modules/security/services/catalog/catalog-plan.ts:planBuiltInPolicy'
        - >-
          services-platform at ad3f6a65: modules/security/db/security-roles.table.ts,
          security-policies.table.ts; services/definitions/manage-roles.ts, manage-policies.ts,
          impact.ts; services/catalog/*.
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-013-14
    title: >-
      Publish shared access definitions from releases with model customer responsibilities with
      roles and policies
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-SEC-012-02
      - BR-CAP-PFM-SEC-013-06
    exercises:
      - CAP-PFM-SEC-013
      - CAP-PFM-SEC-012
    preconditions: A built-in role and a customer-owned copy are both referenced.
    steps: 'Withdraw and republish the built-in in release reconciliation, then read both definitions.'
    expected: >-
      The built-in restores its identity; the customer copy remains a separately editable
      definition.
    negative: false
    data_needs: >-
      An isolated customer with two workspaces, ordinary and staff identities, and records owned by
      this run.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/e2e/definitions.e2e.spec.js#refuses a write against
        a built-in as read-only rather than as a record that is not there
      - >-
        services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#makes
        a retired built-in grant nothing while its holder keeps every other grant
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/definitions.e2e.spec.js#refuses a write
          against a built-in as read-only rather than as a record that is not there
        - >-
          services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#makes
          a retired built-in grant nothing while its holder keeps every other grant
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/e2e/definitions.e2e.spec.js#refuses a write
          against a built-in as read-only rather than as a record that is not there
        - >-
          services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#makes
          a retired built-in grant nothing while its holder keeps every other grant
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
  - id: ATS-PFM-SEC-013-15
    title: Publish shared access definitions from releases with enforce access at request boundaries
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-SEC-013-11
      - BR-CAP-PFM-SEC-015-05
    exercises:
      - CAP-PFM-SEC-013
      - CAP-PFM-SEC-015
    preconditions: An active release serves a protected operation.
    steps: >-
      Stage invalid route declarations, then stage a valid changed release and authorize the shared
      operation.
    expected: >-
      Invalid declarations do not stage; the valid staged and active requirements constrain the
      request together.
    negative: false
    data_needs: >-
      An isolated customer with two workspaces, ordinary and staff identities, and records owned by
      this run.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#answers
        every problem of the release at once, rather than the first one it met
      - >-
        services-platform:modules/security/tests/unit/authorizer/registry-manifest.spec.ts#refuses a
        staffOnly key below a system route
    action_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#answers
          every problem of the release at once, rather than the first one it met
        - >-
          services-platform:modules/security/tests/unit/authorizer/registry-manifest.spec.ts#refuses
          a staffOnly key below a system route
    assertion_evidence:
      provenance: proposed
      source:
        - >-
          services-platform:modules/security/tests/unit/services/catalog/catalog-plan.spec.ts#answers
          every problem of the release at once, rather than the first one it met
        - >-
          services-platform:modules/security/tests/unit/authorizer/registry-manifest.spec.ts#refuses
          a staffOnly key below a system route
    binding_scope: >-
      No executable assertion is bound. The scenario specifies proposed proof and does not establish
      implemented or passing behavior.
evidence:
  - >-
    Pinned services-platform references for the structured rows:
    modules/security/tests/integration/db/security-definition-integrity.integration.spec.js;
    modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js;
    modules/security/tests/integration/services/catalog/release-manifest-built-ins.integration.spec.js;
    modules/security/tests/integration/services/catalog/staff-access-authority.integration.spec.js;
    modules/security/tests/unit/authorizer/registry-publish.spec.ts;
    modules/security/tests/unit/services/catalog/catalog-plan.spec.ts;
    modules/security/tests/unit/services/catalog/export-authority.spec.ts;
    modules/security/tests/unit/services/catalog/reconcile-catalog.spec.ts;
    modules/security/tests/unit/services/catalog/staff-access-authority.spec.ts;
    modules/security/tests/unit/services/persistence/permission-matcher.spec.ts.
  - >-
    Testing back-fill reviews the pinned suite assertions, related capabilities, domain invariants,
    state transitions and workflow failure boundaries. New unbound rows remain proposed.
coverage:
  rule: covered
  transition: covered
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-SEC-070'
  failure: 'gap: FND-PFM-SEC-070'
  boundary: covered
  concurrency: 'gap: FND-PFM-SEC-070'
  invariant: covered
  interaction: covered
coverage_notes:
  edge: No scenario isolates this category. The referenced finding retains the missing design proof.
  failure: No scenario isolates this category. The referenced finding retains the missing design proof.
  concurrency: No scenario isolates this category. The referenced finding retains the missing design proof.
invariant_proofs:
  - scenario: ATS-PFM-SEC-013-05
    proves:
      - INV-DOM-PFM-SEC-003-16
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/services/catalog/reconcile-catalog.integration.spec.js#grants
      a newly shipped built-in to nobody: no role references it
    proof_scope: >-
      Only the cited assertions support this invariant mapping; a source reference does not
      establish a passing execution.
  - scenario: ATS-PFM-SEC-013-09
    proves:
      - INV-DOM-PFM-SEC-003-13
    provenance: test
    source: >-
      services-platform:modules/security/tests/integration/db/security-definition-integrity.integration.spec.js#refuses
      an insert, an update and a delete of a built-in role outside a reconciliation
    proof_scope: >-
      Only the cited assertions support this invariant mapping; a source reference does not
      establish a passing execution.
permission_proof_review: []
examiner: codex
examined_at: '2026-10-23'
final_text: OpenAI
---
# Publish shared access definitions from releases: Capability Test Specification

## Coverage

| Required rule | Scenario or finding |
|---|---|
| `BR-CAP-PFM-SEC-013-01` | `ATS-PFM-SEC-013-01` |
| `BR-CAP-PFM-SEC-013-02` | `ATS-PFM-SEC-013-02` |
| `BR-CAP-PFM-SEC-013-03` | `ATS-PFM-SEC-013-03` |
| `BR-CAP-PFM-SEC-013-04` | `ATS-PFM-SEC-013-04` |
| `BR-CAP-PFM-SEC-013-05` | `ATS-PFM-SEC-013-05` |
| `BR-CAP-PFM-SEC-013-06` | `ATS-PFM-SEC-013-06`, `ATS-PFM-SEC-013-12`, `ATS-PFM-SEC-013-13`, `ATS-PFM-SEC-013-14` |
| `BR-CAP-PFM-SEC-013-07` | `ATS-PFM-SEC-013-07` |
| `BR-CAP-PFM-SEC-013-09` | `ATS-PFM-SEC-013-08` |
| `BR-CAP-PFM-SEC-013-10` | `ATS-PFM-SEC-013-09` |
| `BR-CAP-PFM-SEC-013-11` | `ATS-PFM-SEC-013-10`, `ATS-PFM-SEC-013-15` |
| `BR-CAP-PFM-SEC-013-12` | `ATS-PFM-SEC-013-11` |

The category map records specified proof. A covered category can contain proposed scenarios; it does not mean the checks have run. The bindings identify individual executable contributions, while findings retain missing rules, permissions, transitions and assertions.

## Interactions With Related Capabilities

The interaction scenarios connect this capability to the related actions and workflow handoffs named in their proof references. Each case observes the outcome after the connected action changes records or available authority. A collection of separately bound checks does not establish an ordered feature journey.

Source revisions and assertion references are recorded in frontmatter. Steps and expected observations carry separate evidence annotations. Proposed checks remain distinct from executable test statements, and static review supplies no run result.
