net-kingdom/canon/standards/playbook-capability-contract_v0.2.md
tegwick b808da601d
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Draft execution-attribution and workload-step-up amendments; route remaining tasks
- playbook-capability-contract_v0.2.md (proposed): adds the
  execution-attribution receipt field list (NK-WP-0040-T01).
- iam-profile_v0.4.md (proposed): adds the workload-requested step-up
  contract (acr_values, no-factor refusal, assurance.level to flex-auth)
  (NK-WP-0042-T01).
- Route the remaining externally-owned decisions (NK-WP-0040-T02 to
  audit-core/Railiance, NK-WP-0042-T02 to user-engine, NK-WP-0039-T04 to
  flex-auth/tenant-engine) and mark those workplans blocked.

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 321494@bnt-lap001
Assistant-Session: 2c8a5cd1-573e-4bae-ab2b-29bc6c8ed4e9
2026-09-27 23:59:51 +02:00

386 lines
14 KiB
Markdown

---
id: netkingdom-playbook-capability-contract
type: standard
title: "NetKingdom Playbook Capability Contract v0.2"
domain: netkingdom
status: proposed
version: "0.2"
created: "2026-09-27"
updated: "2026-09-27"
scope: meta-orchestration
supersedes:
- canon/standards/playbook-capability-contract_v0.1.md
adr:
- docs/adr/ADR-0012-playbook-capability-contract-ownership.md
schema:
- canon/schemas/playbook-capability-declaration_v0.1.schema.json
related:
- NK-WP-0040
- history/2026-09-23-railiance-clock-identity-and-layer-review.md
---
# NetKingdom Playbook Capability Contract v0.2
Everything in v0.1 stands unchanged except where this document says
otherwise. v0.1 remains `accepted` and governs declaration conformance;
this document adds the execution-attribution receipt as a proposed
amendment. It becomes conformance-checked only once
`NK-WP-0040-T02` lands the schema, evidence-holder agreement with
audit-core and Railiance, and the corresponding validator addition.
Until then, no declaration is required to emit a receipt.
## Purpose
The Playbook Capability Contract is the declared interface between
NetKingdom meta-orchestration and Railiance execution playbooks.
It lets a playbook state:
- which capability it provisions;
- which parameters it exposes, including defaults, constraints, and
security sensitivity;
- which resources and responsibilities it claims;
- which trust states it requires or satisfies;
- how it is published into a catalog;
- the execution-attribution receipt one run of it emits.
NetKingdom consumes declarations to select playbooks, choose safe
parameter overrides, sequence trust states, and build a responsibility
map. Railiance owns the playbooks and execution mechanics.
## Ownership
NetKingdom owns this contract. Railiance publishes conformant
declarations. Execution stays in Railiance. See ADR-0012.
## File Convention
Declaration files SHOULD live in the publishing repo at:
```text
capabilities/playbooks/<declaration-id>.yaml
```
Each file describes one playbook or one stable playbook entry point. A
playbook with materially different modes may publish multiple
declarations if those modes provide different capabilities or expose
different security-sensitive parameters.
## Top-Level Shape
```yaml
apiVersion: netkingdom.io/playbook-capability/v0.1
kind: PlaybookCapabilityDeclaration
metadata:
id: railiance-infra.bootstrap-host
name: Railiance S1 host bootstrap
owner: railiance-infra
repo: railiance-infra
domain: railiance
contract_version: "0.1"
spec:
playbook: {}
capabilities: []
parameters: []
responsibilities: []
trust: {}
catalog: {}
```
## Capability Vocabulary
`spec.capabilities[].id` MUST be one of the controlled vocabulary values
below. Capability ids are stable comparison keys.
| Capability id | Tier | Meaning |
| --- | --- | --- |
| `s1.os-baseline` | S1 | Host provisioning, OS convergence, hardening, and substrate access baseline |
| `s1.secret-bootstrap` | S1 | Bootstrap secret material, SOPS/age handling, emergency material placement |
| `s2.cluster-runtime` | S2 | Kubernetes runtime, ingress, networking, admission, and cluster access |
| `s3.platform-services` | S3 | Databases, caches, object storage, brokers, and shared platform services |
| `c0.bootstrap-identity` | C0 | Local/bootstrap identity before runtime IAM exists |
| `c1.lightweight-sso` | C1 | key-cape lightweight SSO profile implementation |
| `c2a.light-2fa` | C2a | Lightweight built-in second factor such as TOTP/WebAuthn |
| `c2b.token-authority` | C2b | privacyIDEA or equivalent token authority |
| `c3.runtime-secrets` | C3 | OpenBao or equivalent runtime secret authority |
| `c4.fine-grained-authorization` | C4 | flex-auth and delegated PDP readiness |
| `c5.enterprise-federation` | C5 | expanded-mode Keycloak, enterprise federation, or SAML brokering |
| `c6.self-optimizing-audit` | C6 | audit feedback loops, drift surfacing, and continuous adaptation |
The `S*` entries align to Railiance stack layers. The `C*` entries align
to the NetKingdom capability progression. A declaration may list more
than one capability only when the same playbook entry point truly
provides each one.
## Resource Kinds
Every capability and responsibility claim references one or more
resource kinds:
| Resource kind | Meaning |
| --- | --- |
| `identities` | humans, service accounts, agents, groups, tenants, and assurance evidence |
| `roles_scopes_policies` | roles, scopes, policy packages, protected-system registrations, decision records |
| `secrets_credentials` | bootstrap material, runtime secrets, dynamic credentials, leases, credential rotations |
| `infrastructure_resources` | hosts, runtime, networking, platform services, storage, and deployment substrate |
## Parameter Declarations
Each parameter entry has this shape:
```yaml
- name: swapfile_size_mb
type: integer
required: false
default: 4096
constraints:
minimum: 0
maximum: 65536
sensitivity: operational
tuning_authority: netkingdom_tunable
description: Swap size applied by the bootstrap playbook.
```
Allowed `type` values:
- `string`
- `integer`
- `number`
- `boolean`
- `array`
- `object`
Allowed `sensitivity` values:
- `public` - safe to display and tune freely.
- `operational` - affects behavior or sizing, not secret material.
- `security_sensitive` - affects security posture and requires platform
review.
- `secret_reference` - points to secret material but must not contain the
secret value itself.
Allowed `tuning_authority` values:
- `playbook_default` - NetKingdom should rely on the playbook default.
- `netkingdom_tunable` - NetKingdom may override for a scenario.
- `platform_only` - only platform-control-plane authority may override.
- `tenant_tunable` - tenant-scoped scenario owners may override within
constraints.
- `forbidden` - declaration exposes the value for audit only; callers may
not override it.
Security-sensitive and secret-reference parameters MUST NOT be
`tenant_tunable`. Secret-reference defaults must be references or paths,
not plaintext secret values.
For executable validation, a `secret_reference` value MUST be a non-whitespace
URI such as `openbao://kv/platform/example` or
`kubernetes://namespace/name#key`, or an explicit absolute/relative path
beginning with `/`, `./`, or `../`. Bare strings are rejected because the
composer cannot distinguish them from secret values.
Supported constraints:
| Constraint | Applies to | Meaning |
| --- | --- | --- |
| `enum` | all scalar types | value must be one of the listed values |
| `minimum` / `maximum` | integer, number | numeric bounds |
| `min_items` / `max_items` | array | array length bounds |
| `pattern` | string | regular expression the value must match |
## Responsibility Claims
Responsibility entries feed the responsibility map. They do not transfer
execution ownership to NetKingdom.
```yaml
- resource_kind: infrastructure_resources
owner: railiance-infra
resources:
- server:target_hosts
- os-baseline
repo_owns: Provisioning, convergence, and verification mechanics.
netkingdom_orchestrates: Whether this substrate capability is selected, and which security posture is required.
```
`owner` names the repo or provider that holds execution ownership.
`repo_owns` explains the implementation responsibility.
`netkingdom_orchestrates` explains the meta-orchestration responsibility.
## Trust States And Readiness
Declarations use the trust-state vocabulary from the platform
architecture:
- `bare_host_trust`
- `cluster_trust`
- `bootstrap_secret_trust`
- `bootstrap_identity_trust`
- `runtime_secret_trust`
- `runtime_identity_trust`
- `runtime_authorization_trust`
- `tenant_onboarding_trust`
Each declaration lists states it requires and states it satisfies:
```yaml
trust:
requires:
- state: bare_host_trust
readiness_checks: []
satisfies:
- state: bootstrap_secret_trust
readiness_checks:
- id: sops-age-material-present
description: SOPS/age material is present for bootstrap secrets.
evidence: ansible role sops_agent converged successfully
```
Readiness checks are evidence obligations. The declaration names the
check; the Railiance playbook or verification tooling performs it.
## Catalog And Consumption Model
A catalog is an index of declarations. For v0.1, the catalog mechanism is
file-based:
1. Railiance repos publish declarations under
`capabilities/playbooks/*.yaml`.
2. NetKingdom or a future catalog job discovers those files from known
orchestrated repos.
3. The validator checks each declaration against this contract.
4. A scenario states required capability ids and parameter overrides.
5. NetKingdom selects declarations that provide the required
capabilities.
6. NetKingdom applies only allowed parameter overrides, rejecting
out-of-range, tenant-forbidden, or security-unsafe overrides.
7. NetKingdom composes the responsibility and trust-state claims into a
scenario responsibility map and readiness sequence.
The declaration is not an execution plan. It is the interface that lets a
separate playbook runner execute safely.
## Scenario Shape
The validator supports a small scenario file for single-provider conformance
demos:
```yaml
id: scenario:s1-host-bootstrap-reference
authority: platform
requires:
capabilities:
- s1.os-baseline
parameter_overrides:
railiance-infra.bootstrap-host:
target_hosts:
- railiance01
swapfile_size_mb: 8192
```
Allowed scenario authorities are `platform`, `netkingdom`, and `tenant`.
Tenant authority cannot override `platform_only`,
`security_sensitive`, or `secret_reference` parameters.
The demo composer refuses ambiguous providers and overrides aimed at unselected
declarations. Deterministic multi-provider selection, explicit provider pins,
trust sequencing, responsibility maps, and owner-routed readiness handoffs are
defined by `security-scenario-composition_v0.1.md` and implemented by
`tools/security-scenario-composer/`. Use that contract for operational planning;
the demo path does not authorize or execute playbooks.
## Execution Attribution Receipt (proposed)
Raised by the railiance-clock identity review
(`history/2026-09-23-railiance-clock-identity-and-layer-review.md`,
Ruling 1). IAM Profile v0.3 defines who acts. This contract's
responsibility claims define what is selected and who is responsible.
Neither defines the record that ties **one execution** to its actor
chain, artifact, and result. This section is that record's field list.
It is a proposal: it does not obligate any declaration to emit a receipt
until conformance is enforced per `NK-WP-0040-T02`.
A receipt is a single, non-secret, structured record describing one
completed (or failed) execution of a declared capability. It never
embeds bearer credentials — tokens, secret values, or role response
bodies. Unknown attribution is recorded as an explicit `unknown`, never
inferred from path strings, repository ownership, or convenience
defaults.
### Fields
| Field | Meaning |
| --- | --- |
| `initiator.iss` / `initiator.sub` | Issuer and subject of the initiating actor, from its IAM Profile token |
| `delegation` | The delegation reference (`actor_sub` / `act.sub`) when the initiator acted through a delegating agent; absent, not `unknown`, when there was no delegation |
| `executing_workload` | The authoritative workload binding (Tenancy Posture `workload_identity`, proposed) that ran the playbook |
| `runtime_principal` | The runtime credential's principal identity (e.g. service account, agent runtime identity) that executed it, distinct from the workload binding |
| `tenant` | The tenant the execution acted for |
| `environment` | The environment the execution ran in |
| `run_id` | A stable, unique identifier for this one execution |
| `source_commit` | The source commit of the executed playbook or declaration |
| `artifact_digest` | The content digest of the executed artifact (image, package, or script) |
| `target` | The inventory reference of what the execution acted on |
| `action` | The action taken against the target |
| `decision_refs` | Decision and approval record identifiers that authorized the execution, where one was required |
| `time_interval.start` / `time_interval.end` | The attributed start and end of the execution |
| `time_interval.clock_source` | The clock the interval was measured against |
| `time_interval.bound` | The interval's precision bound, when one exists (e.g. clock skew tolerance); absent when no bound is established, never fabricated |
### Emission and custody (open)
Who emits the receipt, who holds it as evidence, and how a consumer
validates one are not decided by this section. `NK-WP-0040-T02` routes
that decision to audit-core (candidate evidence holder, per the security
layer model's Evidence role) and Railiance (candidate emitter, since it
executes). The receipt schema under `canon/schemas/` and its validator
land together with that agreement, not before it.
### Non-goals
- This is not an authorization decision record. `decision_refs` points at
one; it does not restate it.
- This is not a substitute for the Playbook Capability Contract's
responsibility claims or trust-state readiness checks, which describe
what a declaration is allowed to do, not what one run of it did.
- This does not create a fourth IAM principal type. `executing_workload`
and `runtime_principal` name existing principals and bindings; they do
not grant anything by themselves (railiance-clock review, Ruling 1).
## Conformance
A declaration conforms when it passes:
```text
tools/playbook-capability-contract/playbook_contract_validator.py
```
The validator checks:
- top-level API version and kind;
- required metadata;
- controlled capability ids and tiers;
- resource-kind vocabulary;
- parameter type/default/constraint/sensitivity/tuning rules;
- responsibility claims;
- trust-state and readiness-check shape;
- catalog publication metadata;
- optional scenario selection and parameter override compatibility.
The execution-attribution receipt above is not yet enforced by this
validator; see `NK-WP-0040-T02`.
## Reference Adoption
The reference declaration for v0.1 is in:
```text
../railiance-infra/capabilities/playbooks/railiance-infra.bootstrap-host.yaml
```
It describes the existing Railiance S1 Ansible bootstrap playbook and can
be selected by the sample scenario in:
```text
examples/playbook-capability-contract/scenario-s1-host-bootstrap.yaml
```