Skip to navigation

Service APIs

View as Markdown

APF exposes three local APIs. The OpenShell extension interfaces that the gateway also serves are covered in Adapter Contracts.

APIServed byTransportCallers
PolicyServiceapf-policy-servicegRPC over the Unix socket at --socketThe policy gateway and its OpenShell adapters.
Policy service HTTP APIapf-policy-serviceHTTP at --http-addr, off by defaultOperators, health checks, and the gateway’s JWKS fetch.
EvaluationServiceapf-policy-gatewaygRPC over the Unix socket at --socketCo-located callers that need a decision.

The protobuf definitions are in contracts/proto/nvidia/agent_policy_fabric/. Both Unix sockets have mode 0600 and accept only the UID set by --allowed-uid, which defaults to the service’s own UID.

PolicyService

Package nvidia.agent_policy_fabric.policy_service.v1alpha1, file policy_service/v1alpha1/policy_service.proto.

RPCRequestResponsePurpose
HealthHealthRequestHealthResponseLiveness. Returns HEALTH_STATE_OK.
GetDocumentGetDocumentRequestGetDocumentResponseFetch one projected document with its provenance token.
ListDocumentsListDocumentsRequestListDocumentsResponseList the document names for a surface kind.

GetDocumentRequest

FieldTypeDescription
kindstringSurface kind, such as apf.policy.v1 or openshell.sandbox.v1. Required.
namestringDocument name, such as default.
runtime_contextRuntimeContextCaller identity. With the claims resolver, openshell.user_subject selects a bundle variant, but variants do not work in this release. Refer to Per-Caller Bundle Variants.

GetDocumentResponse

FieldTypeDescription
bodybytesThe projected document.
digeststringHex SHA-256 of body. Callers must check it before use.
versionuint64The bundle’s policy_revision.
valid_until_msuint64Unix milliseconds after which to fetch again. 0 unless --document-ttl-secs is set.
provenance_tokenstringCompact EdDSA JWT binding the document to the bundle. Empty only if minting failed. Refer to Serving Documents for its claims.

Field number 4 is unused. A comment in the contract marks it as reserved.

Surface Kinds

KindNamesBody
apf.policy.v1defaultProtobuf PolicySet.
openshell.sandbox.v1Each SandboxPolicy nameProtobuf OpenShell SandboxPolicy.
openshell.provider-profile.v1default, and each provider namedefault is a protobuf ProviderProfileSet. Named documents are OpenShell provider profile YAML.
apf.policy-rules.v1, apf.policy-annotators.v1, apf.policy-effects.v1, apf.policy-findings.v1defaultJSON arrays of the compiled documents, served when the bundle has any. No APF component consumes them.

Status Codes

RPCStatusMessageAudit record
GetDocument, ListDocumentsINVALID_ARGUMENTkind must be non-empty, or kind '<kind>' is not served by this instancepolicy.document_request_invalid
GetDocumentNOT_FOUNDdocument '<kind>/<name>' not foundpolicy.document_not_found
GetDocumentOKpolicy.document_vended, once per document and revision for each run of the service, and policy.provenance_mint_failed if the token could not be signed
AnyConnection closedA peer with a disallowed UID, or whose credentials cannot be readauth.uds_peer_rejected or auth.uds_peer_cred_failed, and auth.uds_refusals_dropped when refusals arrive faster than they can be recorded

Policy Service HTTP API

Enable it with --http-addr and --http-bearer-token-file. Bind it to loopback unless you have a reason not to.

Method and pathAuthenticationSuccess response
GET /healthNone200 {"state":"ok"}
GET /healthzNone200 {"status":"ok","version":"<version>"}
GET /readyzNone200 {"status":"ok"}, or 503 {"status":"not_ready","reason":"no bundle loaded"}
GET /.well-known/jwks.jsonNone200 JWKS with the document signing key: kty OKP, crv Ed25519, kid, x.
GET /v1/documents/{kind}Bearer token200 {"names":[...]}
GET /v1/documents/{kind}/{name}Bearer token200 {"body":"<base64>","digest":"<hex>","version":<n>}. There is no provenance token on this route. Optional user_subject, sandbox_id, and agent_type query parameters supply the runtime context.
POST /v1/refreshBearer token200 {"status":"refreshed","policy_digest":"<digest>","version":<n>}

Send the token as Authorization: Bearer <token>.

Refresh

With the local source, POST /v1/refresh loads the bundle named in the JSON body and runs the full verification and counter checks:

curl -s -X POST http://127.0.0.1:19200/v1/refresh \
-H "Authorization: Bearer $(cat /path/to/http-bearer-token)" \
-H 'content-type: application/json' \
-d '{"bundle_path": "/etc/apf/bundle/bundle.yaml"}'

The body is required. The service does not fall back to --bundle-path. With the HTTP source, bundle_path is ignored and the call triggers a poll. It returns 200 even when the poll fails, so confirm the outcome in the audit log.

Error Responses

StatusBodyWhenAudit record
400kind must be non-empty, or kind '<kind>' is not served by this instanceThe kind is empty or excluded by --surfaces.policy.document_request_invalid
401missing or invalid bearer tokenThe header is missing, malformed, or wrong.auth.http_bearer_invalid
404document '<kind>/<name>' not foundNo such document.policy.document_not_found
400, 422Generated by the HTTP frameworkA POST /v1/refresh JSON body that is malformed, empty, or has the wrong shape.None
415Generated by the HTTP frameworkA POST /v1/refresh body with a Content-Type other than JSON. A request with no Content-Type is treated as having no body.None
405Generated by the HTTP frameworkThe wrong method for a route.None
500refresh failed: <reason>A local source refresh failed. The active bundle is unchanged.policy.refresh_triggered, plus a policy_verification refusal when verification failed, or a policy.bundle_rejected.counter_persist_failed refusal when the revision could not be recorded
503{"status":"not_ready",...}/readyz before a bundle is loaded.None

Every refresh call that passes authentication and has an acceptable body writes policy.refresh_triggered before the refresh runs.

EvaluationService

Package nvidia.agent_policy_fabric.pdp.v1alpha1, file pdp/v1alpha1/pdp.proto. The gateway serves it on its Unix socket. It decides one request against the active policy set.

grpcurl -plaintext \
-import-path contracts/proto \
-proto nvidia/agent_policy_fabric/pdp/v1alpha1/pdp.proto \
-d '{"verb": "repo_read", "resource": {"class": "github", "id": "octo/repo"}, "args": {"branch": "main"}}' \
unix:///run/apf/policy-gateway.sock \
nvidia.agent_policy_fabric.pdp.v1alpha1.EvaluationService/Evaluate

EvaluateRequest

FieldTypeUse in evaluation
verbstringThe capability. With resource.class, forms the Cedar action APF::Action::"<class>::<verb>".
resource.classstringThe tool. Also the Cedar resource APF::Tool::"<class>". When the request has a resource, it is treated as a tool call and needs a capability grant. Without a resource, the action is APF::Action::"invoke" and the resource APF::Tool::"__none__".
resource.idstringRecorded in the audit record. Not used in evaluation.
resource.attributesmapNot used.
argsmap of stringExposed as context.args. Every value is a string. APF also derives <name>_len for each argument and <name>_num for an argument that parses as an integer. Use <name>_num for numeric comparisons.
context.openshell.user_subjectstringThe Cedar principal APF::User::"<subject>".
context.openshell.sandbox_id, agent_typestringRecorded in the audit record.
context.audit_context["correlation_id"]stringUsed as the audit record’s correlation_id.

The request has no body or target, so content controls that read body_text, body_json, or target.* see nothing.

EvaluateResponse

FieldTypeValue
decisionDecisionDECISION_ALLOW or DECISION_DENY.
reasonstringThe deny reason, empty on allow. Refer to Error Reference.
policy_digest_hexstringDigest of the policy set that decided.
obligationslistAlways empty in this release.
rejection_reasonslistAlways empty in this release.

Effects are evaluated but not applied or returned, so an effect that reads a missing annotation still denies the request. DECISION_REQUIRE_REVIEW, DECISION_REQUIRE_STEP_UP, DECISION_QUARANTINE, and DECISION_STOP_SESSION are reserved and never returned.

An evaluator error returns INTERNAL with evaluator engine error: <detail> and writes no audit record. Every decision writes an authorization record to apf-policy-gateway-audit.jsonl.

RuntimeContext

Package nvidia.agent_policy_fabric.runtime.v1alpha1, file runtime/v1alpha1/runtime.proto. Shared by GetDocument and Evaluate.

FieldTypeDescription
openshell.sandbox_idstringSandbox making the request.
openshell.user_subjectstringSubject the sandbox acts for.
openshell.agent_typestringInformational agent type, such as claude-code.
audit_contextmap of stringFree-form audit metadata. The contract names correlation_id, gateway_id, agent_id, and session_id as well-known keys. Only correlation_id is read, by Evaluate.

Next Steps