Skip to navigation

Bundle Specification

View as Markdown

This page specifies the PolicyBundle format version v1alpha1 as implemented on the main branch. For a guided introduction, refer to Bundle Structure.

Artifact

A signed bundle is one UTF-8 YAML file containing two YAML documents:

  1. The manifest payload, a PolicyBundle document.
  2. After a --- separator, the signature document.

The member documents live in separate files next to the manifest.

Manifest Fields

FieldTypeRequiredFormat and constraints
apiVersionstringYes, by the schemanvidia.agent-policy-fabric.policy/v1alpha1. Not checked at runtime.
kindstringYes, by the schemaPolicyBundle. Not checked at runtime.
metadataobjectNoReserved. Ignored by the runtime.
idstringYesNon-empty. Use only letters, digits, and . _ : @ / + - =, starting with a letter or digit, at most 512 characters. The policy service cannot record an id outside this profile in its audit log and refuses to load the bundle.
descriptionstringNoFree text.
policy_revisionunsigned 64-bit integerYesAt least 1. Refer to Revision Rules.
not_beforestringYesRFC 3339 timestamp.
expires_atstringYesRFC 3339 timestamp. APF does not check that it is later than not_before.
manifestlistNoMembers in evaluation order. Each entry has exactly path and sha256.
manifest[].pathstringYesPath relative to the manifest’s directory.
manifest[].sha256stringYes64 hexadecimal characters, the SHA-256 of the member file’s bytes. Compared without regard to case.
runtime_compatibilitymapNoAdapter name to {min_version, max_version}, as semantic versions. Refer to Runtime Compatibility.

The runtime ignores unknown manifest fields. The JSON Schema rejects them, so validate before signing.

Member paths are joined to the manifest’s directory without normalization. Keep them relative and inside the bundle directory.

Signature Document

---
schema: YamlSigilSignature.v1alpha1
alg: ED25519_PUREEDDSA_RAW_RS64_CANONICAL
keyid: <key id>
signature: <base64url signature>
FieldRequirement
schemaYamlSigilSignature.v1alpha1.
algA yaml-sigil algorithm identifier. apf-compile genfixture produces Ed25519 signatures. Verifiers also accept ECDSA P-256 keys.
keyidRequired. Selects the trust root whose file stem matches.
signatureThe signature over the manifest payload.

Trust Roots

A verifier loads every file in its trust-root directory with one of these extensions. The file name without the extension is the key ID.

ExtensionContents
.pubed25519:<standard base64 of the 32-byte public key> on the first non-comment line.
.pem, .p256An ECDSA P-256 public key in PEM SubjectPublicKeyInfo form.

Member Files

A member file is a YAML document whose kind decides how it is used. Refer to Policy Schemas. A member may itself carry a yaml-sigil signature. APF then uses the member’s payload, but it does not verify the member’s signature against a trust root. The bundle signature, through the manifest digest of the member’s raw bytes, is what protects it.

Verification Order

A verifier processes a bundle in this order.

  1. Signature. Decompose the artifact, resolve keyid in the trust roots, and verify the signature. On failure, stop with signature_invalid.
  2. Parse. Parse the verified payload as a PolicyBundle. On failure, stop with bundle_parse_failed.
  3. Members. For every manifest entry, read the file and compare its SHA-256 with the declared value: manifest_member_unreadable, manifest_hash_unset, or manifest_hash_mismatch.
  4. Validity window. Check not_before and expires_at against the current time: not_before_invalid, expires_at_invalid, bundle_not_yet_valid, or bundle_expired.
  5. Runtime compatibility. Check min_version values: runtime_compat_invalid or runtime_compat_mismatch.
  6. Revision. Check policy_revision against the counter store: counter_regression or counter_content_mismatch.

Steps 3 to 6 all run, and every failure is reported, except that an unparseable not_before or expires_at skips the rest of step 4. The bundle is accepted only if none fails. The policy service then loads and compiles the members, and persists the revision only if compilation succeeds.

For the format of each reason, refer to Bundle Rejection Reasons.

Revision Rules

The counter store holds a high-water mark, the highest accepted policy_revision, and the payload digest accepted at it.

Candidate revisionResult
Greater than the high-water markAccepted.
Equal to the high-water mark, same payload digestAccepted, so a restart can reload the active bundle.
Equal to the high-water mark, different payload digestRejected with counter_content_mismatch. Accepted if the digest record is missing or names another revision, for example after a crash.
Lower than the high-water markRejected with counter_regression.
0Always rejected with counter_regression.

The payload digest is the SHA-256 of the verified manifest payload, without the signature document. Re-signing identical content therefore does not change it.

One counter store serves one policy service, whatever the bundle id. Refer to Expiry and Rollback Protection.

Runtime Compatibility

runtime_compatibility:
openshell:
min_version: "0.1.0"

A verifier compares each min_version with the version of that runtime it is given, after removing a leading v. max_version is not evaluated. In this release the policy service supplies no runtime versions, so APF only checks that each min_version is a valid semantic version.

Manifest Order

KindEffect of order
PolicyRuleEvaluation order. The first rule with a firing forbid decides the deny. Effects apply in rule order.
PolicyAnnotatorDecides which annotator an error about a duplicate key names. Annotators cannot read each other’s output.
PolicyEffect, PolicyFindingNone. They are referenced by name.
SandboxPolicy, Provider, ProviderProfileNone. Projections are produced in name order.

Distribution Archive

The HTTP policy source fetches a gzipped tar archive of the bundle directory. After unpacking, the policy service tries .yaml files in this order and uses the first that verifies against its trust roots and parses as a bundle:

  1. manifest.yaml.
  2. Files whose name contains bundle.
  3. All other .yaml files.

Member paths resolve relative to the chosen manifest.

Contract Definitions

DefinitionLocationNotes
JSON Schemacontracts/jsonschema/policy-bundle.v1alpha1.schema.jsonDescribes the YAML manifest.
Protobufcontracts/proto/nvidia/agent_policy_fabric/policy/v1alpha1/policy_bundle.protoDescribes the bundle model, with metadata, id, description, policy_revision, not_before, expires_at, manifest, and signature. It is not compiled into the services in this release. The signature travels in the yaml-sigil document instead.
Compiled policy setcontracts/proto/nvidia/agent_policy_fabric/policy/v1alpha1/policy_set.protoThe PolicySet served as apf.policy.v1/default, with rules, annotators, effects, and findings in manifest order.
Provider profile setcontracts/proto/nvidia/agent_policy_fabric/policy/v1alpha1/provider_profile_set.protoThe ProviderProfileSet served as openshell.provider-profile.v1/default.

Next Steps