Policy Application Programming Interface
Find Policy API contracts, an ordered lifecycle example, and authorized recovery references.
Use the Policy application programming interface (API) to author and govern policies.
Track delivery separately from approval and target protection.
Approval establishes a governed revision: the approved version of policy intent.
A draft snapshot records saved proposal content, not another approved revision.
Compilation produces target output. Publication and target activation happen separately.
Begin with authentication and shared contracts.
Choose Your Path
Choose the API reference that matches your task:
Operation Families
Choose the reference for the operation you need:
The API base normally uses /pty/policy/v1.0, independently of the application version.
Your deployed /swagger page and /doc document expose its schema.
Use the endpoint-specific runtime rules here when conditional-header descriptions differ.
An entity tag (ETag) is a server-issued resource validator.
Draft commands use Draft-ETag. Archive uses the policy ETag.
Copy the required token unchanged into If-Match to pin the command to inspected state.
Do not substitute the governed policy validator for a current draft token.
1 - Authentication and Shared Request Contracts
Authenticate callers and distinguish command authority, policy grants, draft validators, and ownership preconditions.
Call the Policy application programming interface (API) through your authenticated gateway.
The gateway establishes identity and trusted authorities.
Do not expose the backend directly or supply identity-forwarding headers yourself.
Policy derives audit actors from the authenticated principal.
Never send submittedBy, approvedBy, or an impersonated username in mutation bodies.
Authentication Model
The public API uses the stable /pty/policy/v1.0 path.
That path does not track the Policy application build version.
Use your deployment’s configured external root when it differs.
Helm uses apiService.rootPath. Standalone deployments use SERVER_ROOT_PATH.
Examples assume Bash, curl, and a valid gateway-issued access token.
Obtain your own token through your organization’s approved authentication flow.
Use curl 7.76.0 or later for header-file support and --fail-with-body.
Prepare Credential-Safe Requests
Open a dedicated private Bash session for these requests.
Do not reuse another participant’s shell or credential file.
Set the endpoint without a trailing slash, then enter your token at the hidden prompt.
Enter only the token value, without the Bearer prefix.
The Bash built-ins keep that value out of external-process arguments and shell history.
set +x
set -euo pipefail
umask 077
POLICY_API="https://policy.example.com/pty/policy/v1.0"
unset PPC_ACCESS_TOKEN POLICY_TOKEN
POLICY_CREDENTIAL_DIR=$(mktemp -d "${TMPDIR:-/tmp}/policy-auth.XXXXXXXX")
POLICY_AUTH_HEADER="${POLICY_CREDENTIAL_DIR}/authorization.header"
trap 'rm -rf -- "$POLICY_CREDENTIAL_DIR"; unset PPC_ACCESS_TOKEN POLICY_AUTH_HEADER POLICY_CREDENTIAL_DIR' EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
IFS= read -r -s -p 'Your gateway access token: ' PPC_ACCESS_TOKEN
printf '\n'
if [[ ! "$PPC_ACCESS_TOKEN" =~ ^[A-Za-z0-9._~+/-]+=*$ ]]; then
unset PPC_ACCESS_TOKEN
printf 'Invalid bearer token format; obtain a token through the approved flow.\n' >&2
exit 1
fi
builtin printf 'Authorization: Bearer %s\n' "$PPC_ACCESS_TOKEN" > "$POLICY_AUTH_HEADER"
unset PPC_ACCESS_TOKEN
The private directory permits only its owner to access it.
The header file permits only its owner to read or write it.
Do not export token variables or copy this file into shared storage.
The examples pass only its path to curl, leaving standard input available for payloads.
Keep this shell open while running the requests.
Send the token through the protected header file:
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/version"
Keep tokens out of unprotected or retained files, shared transcripts, source control, and screenshots.
Do not enable shell tracing or curl verbose output around credentials.
Do not print the header file or log authorization headers.
Use normal certificate verification. Do not copy examples with -k.
Obtain each user’s credentials separately through your approved login flow.
Clean up Credentials
Exit the dedicated shell when you finish or hand off to another participant:
The exit trap deletes the header file and its private directory.
It also clears the credential-path variables.
Forced termination or a host crash can prevent trap execution.
Remove that session’s private directory through approved local cleanup if this happens.
Do not retain credential files with response evidence.
Policy Panel Cookie Fallback
Request-driven deployment accepts the gateway’s accessToken cookie when
the request omits the authorization header.
An explicit blank, malformed, or non-bearer header prevents fallback.
Use the gateway’s normal browser protections. Do not spoof forwarded identity.
Policy does not require a separate cross-site request forgery token for these lifecycle commands.
Capabilities and Policy Access
A capability authorizes a command, such as approval.
A policy grant provides owner/editor access to one policy.
Operations that require both reject callers who hold only one.
Responsibilities do not create product roles.
In particular, Policy does not define a separate policy_reviewer role.
Different authenticated users can author, review, and approve.
These command contracts do not themselves enforce two different people.
Follow any additional separation-of-duties rules that your organization requires.
The following table maps each responsibility to its required capability or policy grant:
| Responsibility | Required Capability or Grant |
|---|
| Save or submit an existing draft | Require policy:edit and an active owner/editor policy grant. |
| Restore a governed revision into draft review | Require policy:rollback and an active owner/editor policy grant. |
| Refresh saved validation or request changes | Require policy:review. |
| Approve the reviewed draft | Require policy:approve. |
| Start archive or record withdrawal evidence | Require policy:archive. |
| Read operations, diagnostics, or audit export | Require policy:audit. |
| Reconcile ownership | Require policy:system-configure. Also require archive authority for withdrawal. |
| Read service metrics | Require policy:observability. |
Creation requires policy:edit and grants the creator policy ownership.
An owner/editor grant never creates review, approval, or audit capability.
Grant management requires an active policy owner or an authorized recovery override.
The recovery override remains attributable and auditable.
Do not request broad administrative access merely to complete a review example.
Trusted Authority Mappings
The following table lists trusted authorities and the capabilities each one grants:
| Trusted Authority | Capabilities |
|---|
policy_viewer | Grant policy:view. |
policy_author | Grant view, edit, rollback, compile, and preview capabilities. |
policy_admin | Grant author capabilities plus review, approve, archive, audit, system configuration, and observability. |
policy-library-read | Grant policy:view. |
policy-library-edit | Grant policy:edit and policy:rollback. |
policy-library-admin | Grant view, edit, rollback, review, approve, archive, and audit. Exclude system configuration and observability. |
policy-compile-run | Grant policy:compile. |
policy-realization-plan | Grant policy:preview. |
policy-system-configure | Grant policy:system-configure. |
policy-observability-read | Grant policy:observability. |
Policy combines mapped authorities.
Unmapped authorities grant no capabilities.
Ask your access administrator for the approved deployment mapping.
An operations read does not authorize a retry mutation.
Gateway access rules also apply to backend reads that preserve optional-identity compatibility.
Conditional Requests
An entity tag (ETag) is a server-issued validator for a resource’s inspected state.
The If-Match request header carries that validator as a command precondition.
Use the validator for the resource that the command actually changes.
Use this table to choose the required validator for each command:
| Command | Required Validator |
|---|
| Save, open replacement draft, rollback, cancel, or submit | Echo the current Draft-ETag through If-Match |
| Request changes or approve | Echo the reviewed current Draft-ETag, not the author’s pre-submit token |
| Start ordinary archive | Echo the governed policy ETag through If-Match |
| Decide ownership reconciliation | Echo the registry ETag. Also send inspected generation and Idempotency-Key |
| Enumerate bindings after offset zero | Echo the first page’s registry ETag |
| Retry retained deployment or record archive evidence | Send neither a required validator nor a general idempotency key |
Treat every validator as opaque.
Copy it exactly, including quotes and any weak-token prefix.
Policy reads return both policy and draft validators where applicable.
Saved-validation responses also identify the exact head through Draft-ETag and draftEtag.
Draft summaries expose the token as etag.
Snapshot identifiers identify saved content. Validators protect conditional requests.
Do not use draftVersionId, currentVersionId, or a numeric policy version as a validator.
Submission advances the draft head.
The reviewer must read the submitted head before approving it.
Do not reuse the author’s pre-submit token.
After a conflict, review intervening changes before issuing another command.
Missing required validators return 428.
Draft save, submit, and approval reject a non-draft token with 400.
A changed draft head normally returns 409 with current draft context.
Request-changes also returns 409 for token mismatch or a non-review head.
Policy and registry version conflicts can return 412.
Refer to error reference for response shapes.
Deployment Authentication
Background publication and withdrawal use configured integration credentials.
Request-driven compatibility deployment forwards the authenticated user’s token to Policy Integration Manager (PIM).
That user also needs PIM permission for the requested native changes.
Do not use compatibility deployment for normal governed publication.
Approval queues that publication asynchronously.
Guardrails product-policy reads can record delivery evidence.
GUARDRAILS_CONSUMER_USERNAME selects the eligible consumer identity.
It does not authenticate callers.
The empty-string default permits receipts only for requests with absent or empty identity.
It does not permit named requests.
A nonempty setting requires an exact gateway-verified username match.
Qualifying 200 and 304 retrievals can both record receipts.
Anonymous reads do not qualify with a nonempty setting. Diagnostics under another identity do not qualify.
Keep the consumer’s credentials separate from human and other service credentials.
Neither receipt nor publication proves downstream activation.
The chart maps apiService.environment.GUARDRAILS_CONSUMER_USERNAME through the API ConfigMap into the environment.
This setting does not change gateway access rules.
Refer to Guardrails consumer evidence
for the supported default and completion boundaries.
2 - Policy API Operation Directory
Find canonical operation families and retain links to earlier endpoint references.
The Policy application programming interface (API) uses the stable
/pty/policy/v1.0 base path, independently of the application build version.
Configure POLICY_API for your gateway through the
authentication reference.
Paths identify policies independently of their draft cycles and saved snapshots.
Check each operation’s required capability, resource grant, and validator before calling it.
A successful lifecycle command can accept asynchronous work without completing target delivery.
Choose an Operation Family
Choose the API reference that matches the operation you need:
- Catalog and authoring covers input discovery, compilation, and preview.
- Queries and drafts covers policy reads and draft changes.
- Governance covers submission, review, approval, and archive.
- History and access covers lineage, audit export, and grants.
- Delivery covers consumer retrieval and compatibility deployment.
- Recovery and reconciliation covers diagnostics, retry, and ownership decisions.
- Authoring schemas covers Cedar, actions, and attribute vocabulary.
- Service operations covers health, logs, metrics, and published schemas.
Follow the worked lifecycle for
save, submission, separate-user review, approval, and delivery inspection.
The entries below retain earlier endpoint anchors.
GET /version
Refer to canonical operation reference.
GET /doc
Refer to canonical operation reference.
GET /log
Refer to canonical operation reference.
POST /log
Refer to canonical operation reference.
GET /health
Refer to canonical operation reference.
GET /ready
Refer to canonical operation reference.
GET /live
Refer to canonical operation reference.
GET /catalog
Refer to canonical operation reference.
POST /catalog/recommend
Refer to canonical operation reference.
GET /catalog/principals
Refer to canonical operation reference.
GET /catalog/resources
Refer to canonical operation reference.
GET /catalog/actions
Refer to canonical operation reference.
POST /policies/compile
Refer to canonical operation reference.
GET /policies
Refer to canonical operation reference.
GET /policies/{policy_id}
Refer to canonical operation reference.
GET /policies/{policy_id}/access-grants
Refer to canonical operation reference.
POST /policies/{policy_id}/access-grants
Refer to canonical operation reference.
DELETE /policies/{policy_id}/access-grants/{grant_id}
Refer to canonical operation reference.
POST /policies
Refer to canonical operation reference.
PUT /policies/{policy_id}
Refer to canonical operation reference.
GET /policies/{policy_id}/validation
Refer to canonical operation reference.
GET /validation-diagnostics/{support_reference}
Refer to canonical operation reference.
DELETE /policies/{policy_id}
Refer to canonical operation reference.
POST /policies/{policy_id}/submit
Refer to canonical operation reference.
POST /policies/{policy_id}/request-changes
Refer to canonical operation reference.
POST /policies/{policy_id}/approve
Refer to canonical operation reference.
POST /policies/{policy_id}/archive
Refer to canonical operation reference.
GET /policies/{policy_id}/versions
Refer to canonical operation reference.
GET /policies/{policy_id}/history
Refer to canonical operation reference.
GET /policies/{policy_id}/audit-export
Refer to canonical operation reference.
GET /policies/{policy_id}/operations
Refer to canonical operation reference.
GET /policies/{policy_id}/pim-reconciliations
Refer to canonical operation reference.
POST /policies/{policy_id}/pim-reconciliations
Refer to canonical operation reference.
GET /pim-reconciliations/bindings
Refer to canonical operation reference.
GET /pim-reconciliations
Refer to canonical operation reference.
POST /pim-reconciliations
Refer to canonical operation reference.
POST /policies/{policy_id}/deployments/{deployment_id}/retry
Refer to canonical operation reference.
POST /policies/{policy_id}/archive-evidence
Refer to canonical operation reference.
GET /product-policies/{product_type}
Refer to canonical operation reference.
POST /product-policies/{product_type}/acknowledgements
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
POST /policies/preview
Refer to canonical operation reference.
POST /policies/{policy_id}/deploy
Refer to canonical operation reference.
POST /policies/{policy_id}/deploy/securequery
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
GET /securequery-profiles
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
POST /securequery-profiles
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
GET /securequery-profiles/{profile_uuid}
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
PUT /securequery-profiles/{profile_uuid}
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
POST /securequery-profiles/{profile_uuid}/status
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
POST /securequery-profiles/{profile_uuid}/validate
This release does not register this route. Do not call it.
Refer to product delivery for current consumer contracts.
GET /schema/cedar
Refer to canonical operation reference.
GET /schema/actions
Refer to canonical operation reference.
GET /schema/authoring-actions
Refer to canonical operation reference.
GET /schema/attributes
Refer to canonical operation reference.
3 - Save, Review, Approve, and Inspect Delivery
Follow a separate-user API handoff using current draft validators and independent delivery evidence.
This application programming interface (API) example follows one Data policy.
The author saves and submits. Another authorized user reviews and approves.
An authorized auditor then inspects delivery.
Separate accounts demonstrate a handoff, not mandatory two-person enforcement.
Before You Begin
Prepare the following before running requests:
- Use Bash, curl, jq, and a writable local working directory.
- Read authentication and authority.
- Give the author
policy:edit. Creation supplies its owner grant. - Give the reviewing account
policy:review and policy:approve through approved mappings. - Give the auditor
policy:audit for delivery inspection. - Prepare working discovery, identity, and Policy Integration Manager (PIM) integrations.
- Select a supported Data classification, principal, and discovered resource.
Do not grant broad administrator access just to copy this example.
Use your deployment’s existing, approved authority assignments.
Do not share tokens between participants.
The selected principal receives null-read permission, not cleartext access.
Follow your organization’s review rules before running mutations.
Prepare Safe Variables
Each participant supplies only their own token in their own session.
Complete the credential-safe request setup
in each participant’s dedicated Bash session.
Each participant creates their own protected header file through the hidden prompt.
Use the same POLICY_API and policy identifier across the handoff.
Do not enable shell tracing, print the token, or log authorization headers.
Follow credential cleanup
when each participant finishes.
set -euo pipefail
: "${POLICY_API:?Set the deployment endpoint during authentication setup}"
: "${POLICY_AUTH_HEADER:?Complete authentication setup with your own author token}"
Retain only safe response bodies and headers, never the temporary credential file.
The helper preserves the exact draft token:
draft_etag() {
awk '
tolower($1) == "draft-etag:" {
sub(/\r$/, "")
sub(/^[^:]*:[[:space:]]*/, "")
value = $0
}
END {
if (value == "") exit 1
print value
}
' "$1"
}
Save as the Author
As the author, complete these steps to prepare and save the draft:
Retrieve the current selection catalogs.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog" -o catalog.json
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog/principals" -o principals.json
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog/resources" -o resources.json
The responses identify available classifications, principals, and discovered resources.
Choose a PIM-supported principal and matching resource classification.
Stop if integration evidence or supported selections are missing.
Set the selected catalog identifiers in your session.
: "${CLASSIFICATION:?Set an exact classification identifier from the catalog}"
: "${PRINCIPAL_ID:?Set the selected supported principal identifier}"
: "${RESOURCE_ID:?Set the selected matching discovered resource identifier}"
Generate the complete create payload.
jq -n \
--arg classification "$CLASSIFICATION" \
--arg principal "$PRINCIPAL_ID" \
--arg resource "$RESOURCE_ID" \
'{
readableName: "Reviewed customer record protection",
source: "data",
compileRequest: {
classificationsInScope: [$classification],
enforcement: [{
enforcementPoint: "data-protection",
effect: "permit",
anyPrincipal: false,
principalIds: [$principal],
actions: ["viewNull"],
resourceIds: [$resource]
}],
protectionIntents: [{classification: $classification}]
}
}' > create-policy.json
The server derives protection methods from the selected inputs.
An empty actions list does not mean null-read permission.
Optional trusted applications belong in compileRequest.trustedApplications, separately from permission principals.
Save the draft.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @create-policy.json \
-D create.headers -o create-response.json \
"${POLICY_API}/policies"
POLICY_ID=$(jq -er '.policy.id' create-response.json)
DRAFT_ETAG=$(draft_etag create.headers)
jq '.policy | {id, policyState, draftState, outstandingExceptions}' \
create-response.json
Expect 201, a policy identifier, and a Draft-ETag header.
Save creates a draft. It does not approve or publish it.
Save can retain validation findings that prevent later submission.
Keep POLICY_ID for policy paths. Do not replace it with draftPolicyId or a snapshot identifier.
The draftPolicyId identifies the stable Draft Policy. The draft summary’s cycleNumber identifies its cycle.
Submit and Hand Off
As the author, complete these steps to submit the current draft and hand it off:
Submit the exact saved head as the author.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "If-Match: ${DRAFT_ETAG}" \
-D submit.headers -o submit-response.json \
"${POLICY_API}/policies/${POLICY_ID}/submit"
jq '.policy | {id, policyState, draftState, enforcementState}' \
submit-response.json
Expect 200 with the draft entering in_review.
Submission advances its token and queues no publication.
If validation blocks submission, stop and inspect the returned safe findings.
Correct hard conflicts. Do not manufacture acknowledgements.
For reviewable findings, follow the notes and conflict-identifier requirements in the
submission contract.
Give the reviewer the policy identifier and review context.
Do not give them your token or pre-submit validator.
They authenticate separately and retrieve the current submitted content.
Review as Another User
As the reviewer, complete these steps to review the submitted draft:
Authenticate in the reviewer’s session.
Complete the credential-safe request setup
with the reviewer’s own token in a separate dedicated Bash session.
Do not copy the author’s credential file or token.
set -euo pipefail
: "${POLICY_API:?Set the same deployment endpoint during authentication setup}"
: "${POLICY_ID:?Use the policy identifier supplied for review}"
: "${POLICY_AUTH_HEADER:?Complete authentication setup with your own reviewer token}"
Read the current policy.
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-D review.headers -o review-policy.json \
"${POLICY_API}/policies/${POLICY_ID}"
jq '.policy' review-policy.json
Review the scope, principal permission, method, and current draft state.
Stop if the draft no longer represents the submitted proposal.
Refresh saved validation with review authority.
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-D validation.headers -o validation.json \
"${POLICY_API}/policies/${POLICY_ID}/validation"
jq -e '.draftStatus == "in_review" and .cedarValid == true
and (.conflicts | length == 0)' validation.json
REVIEWED_DRAFT_ETAG=$(jq -er '.draftEtag' validation.json)
Expect 200, current draft identifiers, findings, and the same token in Draft-ETag.
This clean-path example stops when conflicts exist.
An author without review capability cannot use this endpoint.
The approver must reconsider any changed findings before acknowledgement.
Compare the validated head with the content just reviewed.
If it changed during the handoff, reread the content before approving.
Do not parse the token to infer that content stayed unchanged.
Approve the submitted draft using the validator returned by validation.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${REVIEWED_DRAFT_ETAG}" \
--data '{"reviewNotes":"Reviewed selected scope and null-read permission.","acknowledgedConflictIds":[]}' \
-o approve-response.json \
"${POLICY_API}/policies/${POLICY_ID}/approve"
jq '.policy | {id, policyState, governedRevision, draftState, enforcementState}' \
approve-response.json
Expect 200, a governed revision, and asynchronous publication work.
Policy revalidates current dependencies before accepting approval.
A stale token or changed validation requires another review, not blind retry.
Never send approvedBy. Policy records the authenticated approver.
Request Changes Instead
The reviewer can return the submitted head without changing its authored content:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${REVIEWED_DRAFT_ETAG}" \
--data '{"reason":"Narrow the selected resource scope before approval."}' \
"${POLICY_API}/policies/${POLICY_ID}/request-changes"
Expect 200 with draft.draftStatus: "changes_requested" and a new draft.etag.
The author reloads the returned draft, corrects the complete compileRequest,
saves through PUT /policies/{policy_id}, and submits again.
Use the new current draft token for each command.
This alternative replaces approval. Do not execute it after approving.
Inspect Delivery as an Auditor
As an auditor, complete these steps to inspect delivery evidence:
Authenticate as an authorized auditor and inspect operations.
Complete the credential-safe request setup
with the auditor’s own token in a separate dedicated Bash session.
Do not copy the author’s or reviewer’s credential file or token.
Set POLICY_API and POLICY_ID to the same endpoint and policy used in the handoff.
: "${POLICY_AUTH_HEADER:?Complete authentication setup with your own auditor token}"
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/operations" \
-o operations.json
jq '.[] | {deploymentId, generation, operation, enforcementState,
retryable, attemptCount, diagnostics}' operations.json
Expect 200 with a top-level operation array.
Retain the deployment identifier and generation for any authorized recovery.
Read current protection evidence separately.
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}?view=governed&includeProtection=true" \
-o delivery-policy.json
jq '.policy | {policyState, governedRevision, enforcementState, protectionConfirmation}' \
delivery-policy.json
The governed view selects approved inputs, not an open replacement draft’s scope.
The default view=latest selects that draft’s content instead.
Compare the current governed revision, deployment, and expected locations with current observations.
Approval, successful publication, and consumer receipt do not independently prove protection.
Verify target-specific behavior through your approved protection checks.
Verification and Failure Boundaries
Keep the saved policy identifier, reviewed draft version, governed revision,
deployment generation, and safe validation evidence.
History attributes the submitter and approver to their actual identities.
Review or audit capability controls restricted decision-note visibility.
For 409 or 412, reread and reassess intervening changes.
For missing authority, stop and request the appropriate approved access.
For publication failures, follow the
recovery playbook.
Do not call compatibility deployment to force governed publication.
Retained retry does not compile corrected drafts.
4 - Application Programming Interface Errors and Safe Recovery
Interpret Policy API failures without confusing stale drafts, unavailable evidence, and retryable delivery work.
Interpret errors within the operation’s application programming interface (API) contract.
The same status can describe different resources and corrective actions.
Interpret Hypertext Transfer Protocol (HTTP) statuses alongside the response body.
Retain the method, path, status, safe response body, and timestamp.
Keep credentials and sensitive request values out of escalation evidence.
Common HTTP Status Codes
Use this table to interpret common HTTP status codes and identify a response:
| Status | Meaning and Response |
|---|
304 | Reuse the cached consumer payload when its validator matches. Treat this as successful conditional retrieval. |
400 | Correct malformed parameters or the wrong validator type before repeating the request. |
401 | Authenticate through the gateway with your own valid token. |
403 | Obtain the operation’s capability or required policy grant through approved access management. |
404 | Check the operation-specific absence meaning. Do not assume every response proves a missing policy. |
409 | Read the error message. Reload the draft before editing, the operation list before delivery retry, or ownership inspection before reconciliation. |
412 | Repeat the read that supplied the ETag. Compare the updated content before preparing a request with the new validator. |
422 | Correct schema violations or validation findings. Preserve the support reference when present. |
428 | Read the correct resource and supply its required conditional header. |
500 | Save the error and request time. Check policy detail and history to determine whether the command completed before retrying. |
502 | Send the returned deployment error and policy identifier to the Policy Integration Manager (PIM) administrator to check for partial changes. |
503 | Ask the administrator of the named integration to restore access. A failed PIM inventory request does not mean its objects are absent. |
For draft commands, a non-draft token normally produces 400.
A stale draft token normally produces 409, not uniformly 412.
Archive uses the policy token. Reconciliation uses the ownership-registry token.
Refer to conditional requests.
An operations 404 can mean no recorded deployments.
A diagnostics 404 can mean expired evidence.
A saved-validation 404 can mean no draft.
Read the status-code description for the endpoint you called before deciding what to retry.
Error Response Shapes
Common service errors use message and optional causedBy fields.
Workflow errors use detail, which can contain a string, object, or validation list.
Do not assume every error contains detail.code.
Compile, submission, and approval can return structured validation failures.
The following example illustrates an approval failure. Do not expect its code from every operation:
{
"detail": {
"code": "approval_validation_failed",
"message": "Approval cannot continue until the validation findings are resolved.",
"conflicts": [],
"issues": [
{
"path": "$.user_attribute",
"constraint": "required",
"message": "Set the identity source user attribute."
}
],
"supportReference": "VAL-example"
}
}
An authorized auditor can retrieve retained evidence through
validation diagnostics.
Records expire after seven days.
The support reference itself does not authorize access.
If you lack policy:audit, retain the safe failure response and reference for an authorized auditor.
Compare each issues[].path with the request schema for the endpoint.
If the message describes an identity-source setting, as in the example, send it and the support reference to the identity integration administrator.
Do not add an unfamiliar configuration field to your policy request merely because the error names it.
Draft conflicts can include detail.currentDraft, with the current etag,
currentVersionId, and draft identity.
Reload policy detail and compare the saved draft with your intended changes before retrying.
Archive-evidence location conflicts can include detail.unexpectedLocationIds.
Ownership conflicts can include the changed affected-policy set or revision map.
Ordinary schema failures can contain a validation-error list instead.
For a changed draft, read current content and validation with the required authority.
Correct the selected input or review the new findings before resubmitting.
After retrying, reload the policy to check the saved content and status.
For publication failures, follow the delivery verification guides.
Retry and Idempotency Guidance
No general idempotency key makes every lifecycle command replay-safe.
After a timeout, first read current policy, history, and permitted operation evidence.
The server might have accepted a command before the connection failed.
Reconciliation decisions require an Idempotency-Key.
An identical accepted decision can replay without another ownership transition.
Keep the original actor, body, registry token, and key for that exact replay.
Changed evidence requires inspection and a new decision.
Retained deployment retry requires no general idempotency key.
It restarts eligible work that stopped after failure.
A repeated request can return 409 while that work is already running again.
Archive-evidence submission can append another immutable event when repeated.
Check history before repeating it after an uncertain result.
Endpoint Groups and Expected Error Patterns
Use this table to identify the correction boundary for each operation family:
| Family | What to Check Next |
|---|
| Catalog, compile, and preview | Correct supplied inputs or ask the integration owner to restore missing configuration. |
| Draft save and submission | Reload the draft and correct the fields named in validation messages. |
| Review and approval | Reload the submitted draft and validation results using the reviewer’s own account. |
| Archive and retry | Read the operation list and select the latest publication or removal request. |
| Reconciliation | Repeat ownership inspection and build the decision from its current allowedActions, identifiers, versions, and ETag. |
| Product retrieval | Check the consumer’s HTTP response. Use Guardrails monitoring separately to confirm that it applies the retrieved configuration. |
Only acknowledge conflicts that explicitly permit acknowledgement.
Never acknowledge a hard validation failure or shared-protector permission widening.
An author without review capability cannot use saved validation as an unrestricted diagnostic shortcut.
An operator may need to repair integrations before the author can continue.
For ownership mismatches, use explicit reconciliation inspection and allowed decisions.
Do not assume waiting for a background refresh authorizes adoption or replacement.
Retrying delivery reuses retained artifacts. It does not compile corrected drafts.
There is no public run-now endpoint for automatic recompilation.
5 - Service and Schema Publication Operations
Reference the request, response, and failure contracts for this operation family.
Use the configured POLICY_API base and protected POLICY_AUTH_HEADER file from
authentication.
All paths below are relative to that base.
Examples read the bearer header from that file. Keep request payloads and logs free of credentials.
Consult your deployed /doc document for complete nested schemas.
Response examples illustrate relevant fields rather than every optional property.
These application programming interface (API) reads return direct payloads.
Most reads return 200. Readiness and liveness return empty 204 responses.
Gateway access rules can still return 401 or 403.
Backend health reads do not independently certify target activation or worker completion.
GET /version
Retrieve runtime API version.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/version"
- Response
- Version object.
Sample response:
{
"version": "1.1",
"buildVersion": "1.1.0"
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /doc
Retrieve OpenAPI specification as YAML.
OpenAPI describes request and response schemas.
YAML is the document format returned by this route.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/doc"
- Response
- OpenAPI YAML document.
Sample response:
openapi: 3.1.0
info:
title: Policy Compiler API
Error codes:
Possible error codes are 401, 403, and 500.
GET /log
Retrieve current runtime log level.
This operation returns the configured level, not log entries or diagnostic records.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/log"
- Response
- Current log level.
Sample response:
Error codes:
Possible error codes are 401, 403, and 500.
POST /log
Update runtime log level.
Require policy:system-configure.
This change applies to the serving process, not persistent cluster configuration.
- Path parameters
- None.
- Request body
- JSON with desired log level.
- Request parameters
- None.
Sample request:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-d '{"level":"debug"}' \
"${POLICY_API}/log"
- Response
- Updated log level.
Sample response:
Error codes:
Possible error codes are 400, 401, 403, and 500.
PUT /log
Use the compatibility method for the same process-local log update.
Require policy:system-configure. Accept no path or query parameters.
Send an application/json object with the required string level.
Supported values include debug, info, warn, and error.
The server also accepts legacy uppercase forms.
curl --fail-with-body -X PUT \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data '{"level":"info"}' \
"${POLICY_API}/log"
Return 200 with {"level":"info"}.
Return 400 for invalid levels, 401 or 403 for identity or capability failures,
or 500 for server failures.
Neither log-update method requires If-Match or an idempotency key.
GET /health
Retrieve service health status.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/health"
- Response
- Health status object with component checks.
Sample response:
{
"isHealthy": true,
"checks": [
{
"passed": true,
"output": "Catalog loaded successfully",
"componentType": "catalog",
"componentName": "catalog"
}
]
}
Error codes:
Possible error codes are 401, 403, and 503.
GET /ready
Readiness probe endpoint.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -i -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/ready"
- Response
- Empty body with readiness status code.
Sample response:
Error codes:
Possible error codes are 401, 403, and 503.
GET /live
Liveness probe endpoint.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -i -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/live"
- Response
- Empty body with liveness status code.
Sample response:
Error codes:
Gateway authentication or authorization failures return 401 or 403.
Liveness failures return 503.
GET /openapi.json
Retrieve the generated OpenAPI schema as JavaScript Object Notation (JSON).
Accept no body, path parameters, or query parameters.
Apply gateway authentication as your deployment requires.
Return 200 with the schema document.
Gateway failures can return 401 or 403. Server failures can return 500.
This automatic schema route does not appear as an operation inside its own document.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/openapi.json"
GET /swagger
Open the browser reference for the deployed schema.
Accept no body or parameters. Return 200 with Hypertext Markup Language (HTML).
The page loads its schema and initializer from the same API root.
Gateway failures can return 401 or 403. Rendering failures can return 500.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/swagger"
GET /swagger/init.js
Serve the Swagger browser initializer.
Accept no body or parameters. Return 200 with JavaScript.
This auxiliary route supports the browser reference, not policy mutation.
Gateway failures can return 401 or 403. Server failures can return 500.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/swagger/init.js"
GET /favicon.ico
Serve the browser reference’s empty icon response.
Accept no body or parameters. Return 200 with the image/x-icon media type.
This auxiliary route carries no policy or health evidence.
Gateway failures can return 401 or 403.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/favicon.ico"
GET /metrics
Read service metrics in Prometheus exposition format.
Require policy:observability. Accept no body or parameters.
Return 200 with metric text, not a JSON response.
Return 401 or 403 for identity or observability failures.
Metrics collection can also encounter server failures.
This route does not appear in the generated operation schema.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/metrics"
Use metrics with operation history and
automatic recompilation observations.
Check authenticated catalog access separately. A successful health probe does not test every integration operation.
For a failed probe, retain the status, timestamp, and safe health-check output when available.
Ask the platform operator to investigate readiness or dependency failures.
Wait for the operator to restore service before repeating an authoring request.
6 - Catalog, Compilation, and Preview Operations
Reference the request, response, and failure contracts for this operation family.
Use the configured POLICY_API base and protected POLICY_AUTH_HEADER file from
authentication.
All paths below are relative to that base.
Examples read the bearer header from that file. Keep request payloads and logs free of credentials.
Consult your deployed /doc document for complete nested schemas.
Response examples illustrate relevant fields rather than every optional property.
These application programming interface (API) operations do not save or approve policies.
Catalog reads expose discovered vocabulary. Compilation and preview evaluate supplied intent.
Require policy:compile for compilation and policy:preview for native preview.
Successful operations return 200.
For commands using request.json, prepare the complete compile body before running curl.
The worked payload construction
shows how to build a bounded compileRequest from current catalog identifiers.
For compilation or PIM preview, save that nested object’s contents as request.json, without the outer create-policy fields.
Policy Integration Manager (PIM) supplies the native Data target.
Build each compile request from current catalog selections.
Use classification identifiers from /catalog, principal id values from /catalog/principals,
and resource id values from /catalog/resources.
Place principal and resource identifiers in the corresponding enforcement row’s principalIds and resourceIds arrays.
Use the exact ID returned by the appropriate current catalog. Do not substitute a display label or an identifier from a different API.
Catalog retrieval does not populate a server-side authoring session.
Send the complete accumulated input with each compile or preview request.
GET /catalog
Retrieve Policy catalog vocabulary bundle.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog"
- Response
- Catalog bundle.
Sample response:
{
"classifications": ["EMAIL_ADDRESS"],
"classificationDetails": {
"EMAIL_ADDRESS": {"label": "Email address"}
},
"protectionMethods": ["FPE"]
}
Error codes:
Possible error codes are 401, 403, and 500.
POST /catalog/recommend
Recommend protection methods for supplied items.
- Path parameters
- None.
- Request body
- Items with classification and profile toggles.
The table lists item fields, their data types, and requirements or defaults:
| Item Field | Type | Requirement or Default |
|---|
id, classification | Strings | Supply the caller’s correlation key and exact classification identifier. |
reversible, protectAtRest, formatPreserving | Booleans | Default to true. |
lowEntropy, beyondLatin1 | Booleans | Default to false. |
Place items in the top-level items array. Omission defaults to an empty array.
The response omits items whose classification yields no modeled method.
Recommendation does not establish that every method supports your selected target.
- Request parameters
- None.
Sample request:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-d '{"items":[{"id":"customer_email","classification":"EMAIL_ADDRESS"}]}' \
"${POLICY_API}/catalog/recommend"
- Response
- Recommended methods per item.
Sample response:
{
"methods": {
"customer_email": "FPE"
}
}
Error codes:
Possible error codes are 400, 401, 403, 422, and 500.
GET /catalog/principals
Retrieve principal catalog for the Who step.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog/principals"
- Response
- Principal entries and total count. When identity-source provenance is
available, entries include normalized
provider values, the source-supplied
discovery.principalUuid, and pimSupported. Unsupported Data Protection
principals include a pimUnsupportedReason. Unknown source compatibility is
left unset rather than inferred.
Use each entry’s exact id for policy selection. name is a display label.
Do not infer an ID format or reject a UUID that the catalog returns.
Select a PIM-supported principal for Data authoring.
An unset pimSupported value does not establish support.
Directory membership does not grant Policy command authority.
Sample response:
{
"total": 1,
"principals": [
{
"id": "user-123",
"name": "Example reader",
"type": "User",
"provider": "IDP",
"discovery": {
"principalUuid": "{{PRINCIPAL_UUID}}",
"sourceId": "{{IDENTITY_SOURCE_ID}}",
"sourceSystem": "idp_ldap"
},
"pimSupported": true,
"pimUnsupportedReason": null
}
]
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /catalog/resources
Retrieve resource catalog for the Protection step.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog/resources"
- Response
- Resource entries and total count.
Use the returned resource id in the compile request.
Catalog protection labels describe discovered or derived information, not confirmed target activation.
If a required resource is missing, ask the discovery integration owner to check its source.
Do not fabricate an identifier to bypass missing discovery evidence.
Sample response:
{
"total": 1,
"resources": [
{"id":"schema.table.column","name":"Example column","type":"Column"}
]
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /catalog/actions
Retrieve action catalog for permissions matrix.
This catalog differs from the native and abstract authoring action vocabularies.
Use /schema/authoring-actions for abstract compile actions and /schema/actions for native schema actions.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/catalog/actions"
- Response
- Action vocabulary.
Sample response:
{
"actions": [
{
"id": "ca-1",
"name": "read",
"category": "data-access",
"applicableLayers": [1, 2, 3, 4, 5],
"description": "Read/select rows from a table or column"
}
]
}
Error codes:
Possible error codes are 401, 403, and 500.
POST /policies/compile
Compile a policy and return its validation report and emitted entities.
- Path parameters
- None.
- Request body
- Compile request payload. The optional
trustedApplications array contains
application gates for PIM datastores, separate from user and group permission
principals. Each entry has an applicationName and one or more
applicationUsers. Refer to deployed OpenAPI document for field constraints. - Request parameters
- None.
The public compile body accepts these top-level fields:
| Field | Type | Default or Meaning |
|---|
classificationsInScope, frameworks | Arrays of strings | Default to empty arrays. |
sensitivityOverrides, protectionOverrides | Objects mapping strings to strings | Default to empty objects. |
sensitivityApproved | Array of strings | Default to an empty array. |
configOverrides | Object | Default to empty. Map resource identifiers to typed protection configuration. |
identity | Boolean | Default to true. |
policyName, policyUuid | Nullable strings | Optionally identify compilation context. Saving uses server-owned identity. |
enforcement | Array of objects | Default to empty. Supply enforcement point, principal/action scope, and resource identifiers. |
protectionIntents | Array of objects | Default to empty. Supply classification and method-selection signals. |
trustedApplications | Array of objects | Default to empty. Supply application names and application-user arrays. |
federated_guardrails | Nullable object | Supply native Federated Guardrails rules or permission matrix. |
Use the deployed schema for typed configOverrides and native rule definitions.
An empty request can span broad discovery inputs. Prefer explicit bounded scope.
Compilation returns findings without creating a draft or changing protection.
Inspect the returned report, not only the 200 status.
Neither compiled entities nor a successful preview establish submission eligibility or target protection.
Sample request:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @request.json \
"${POLICY_API}/policies/compile"
- Response
- Final compile report plus Cedar and PIM entities.
Sample response:
{
"report": {},
"cedarEntities": [],
"pimEntities": []
}
Error codes:
Possible error codes are 400, 401, 403, 422, and 500.
POST /policies/preview
Preview a policy’s native lowering without applying changes.
- Path parameters
- None.
- Request body
- Product-specific preview payload.
Use
product=PIM for a bare compile request.
Use product=FEDX for a Federated Guardrails object with required compile
and optional guardrail_rules, dataprotection_rules, content_action_rules, or federated_matrix. - Request parameters
product is required and accepts PIM or FEDX.
The optional boolean reuse_existing defaults to true for PIM inventory reuse.
Inventory reuse concerns native resource planning. It is not a replay or idempotency guarantee.
Sample request:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @request.json \
"${POLICY_API}/policies/preview?product=PIM&reuse_existing=true"
- Response
- Product-specific native plan object. For
product=PIM, datastore_scopes
can contain an individual registration scope or a shared protector-group scope.
Group scopes retain each source registration, its approved IPv4 ranges, and
source columns, alongside the group’s canonical range union. The plan can also
include source-sensitive authorization evidence used to check that sharing a
native datastore does not widen permissions.
Sample response:
{
"plan": {
"operations": [],
"datastore_scopes": {
"{{DATASTORE_GROUP_REF}}": {
"schema_version": 2,
"group_id": "{{PROTECTOR_GROUP_ID}}",
"ranges": [["192.0.2.10", "192.0.2.10"]],
"sources": [{
"registration_id": "{{SOURCE_REGISTRATION_ID}}",
"ranges": [["192.0.2.10", "192.0.2.10"]],
"source_columns": ["{{SOURCE_COLUMN_ID}}"]
}]
}
},
"authorization": {
"schema_version": 1,
"policy_id": "${POLICY_ID}",
"resources": [],
"native_grants": []
}
}
}
Error codes:
Possible error codes are 400, 401, 403, 422, and 500.
7 - Policy Queries and Draft Operations
Reference policy reads, server-validated draft creation, saved snapshots, rollback, and cancellation.
These application programming interface (API) operations inspect and save policy work.
Use POLICY_API and the protected POLICY_AUTH_HEADER file from
authentication.
Saved drafts, governed revisions, and protection states remain independent.
Response examples show relevant fields, not every optional property.
Use the policy identifier in {policy_id} paths, including draft commands.
Set POLICY_ID to that identifier before running examples for an existing policy.
The separate draftPolicyId identifies the stable Draft Policy, not a replacement path identifier.
The draft summary’s cycleNumber identifies its authoring cycle.
Each save records a draft snapshot. Repeated saves do not create new proposed major revisions.
Approval establishes a governed revision. A compilation minor identifies output within that approved revision.
Neither snapshot identifiers nor revision numbers replace server-issued validators.
GET /policies
List visible policy summaries and aggregate counters.
The backend permits optional identity for this compatibility read.
Gateway access rules still apply.
Accept no body or path parameters.
The following table lists supported query parameters and their types and behavior:
| Query Parameter | Type | Requirement |
|---|
search | Optional string | Filter names by a case-insensitive substring. |
status | Optional status string | Select a compatibility policy status from the deployed enum. |
limit | Optional integer | Bound the returned page. Omission returns the unbounded selected set. |
offset | Optional integer | Select the starting position. Omission starts at zero. |
includeProtection | Boolean | Request live protection readback. Default to false. |
view | String | Select latest by default, or governed for approved content while a draft remains open. |
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies?limit=20&offset=0&view=latest"
Return 200 with total, dataCount, aiCount, approvedCount, draftCount,
and a policies array.
Each summary identifies id, compatibility status, source, and independent
policyState, draftState, and enforcementState values.
Additional fields describe names, scope, method, validation, and available actions.
governedRevision identifies the approved major revision.
governedMinorVersion identifies compilation output within that revision.
draftPolicyId, draftCycleNumber, and proposedRevisionNumber identify open draft work.
hasOpenDraft distinguishes an approved policy with a replacement proposal.
validationStatus describes authoritative, unavailable, or stale saved validation.
operationIssue summarizes delayed or failed delivery.
availableActions lists actions offered to the caller.
A command can still fail if permissions or policy content change after the read.
Counters use the search-filtered set before the status filter.
For bounded reads, send limit and offset explicitly and retain the same filters and view on later pages.
Do not use aggregate counters as page lengths.
includeProtection=true queries the integrations for current protection observations and can take longer than a stored-state read.
Gateway failures can return 401 or 403. Malformed query values return 422.
Dependency failures can return 503. Server failures can return 500.
GET /policies/{policy_id}
Inspect one policy’s full content and independent state projections.
Require the policy_id path string. Accept no body.
Support the same includeProtection and view query options as listing.
The backend permits optional identity. Gateway access rules still apply.
curl --fail-with-body -i -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}?view=latest"
Return 200 with a policy object.
The object includes id, readableName, version, status, authored fields,
trusted actor attribution, validation findings, and independent state projections.
Imported external records can expose origin, displayOnly, and editable.
includeProtection=true can populate protectionConfirmation.
The response supplies the policy ETag and, when available, Draft-ETag.
Draft commands require the latter.
Use view=latest to inspect current proposal content before a draft command.
Use view=governed to inspect approved content while a replacement draft remains open.
A policy’s approved governance state does not make its open draft approved.
{
"policy": {
"id": "policy-1",
"status": "approved",
"policyState": "approved",
"governedRevision": 3,
"governedMinorVersion": 1,
"hasOpenDraft": true,
"draftState": "in_review",
"enforcementState": "enforced"
}
}
Return 404 for an unknown policy.
Gateway failures can return 401 or 403. Invalid query values return 422.
Live integration failures can return 503. Server failures can return 500.
POST /policies
Create a new policy identity and its first saved draft.
Require policy:edit. Accept no path or query parameters.
Creation grants policy ownership to the authenticated creator.
No prior validator or idempotency key applies.
The application/json body rejects extra fields:
| Field | Type | Requirement |
|---|
readableName | String | Supply the policy’s display name. |
compileRequest | Object | Supply the complete compile input that Policy will validate before saving. |
source | Optional string | Select data or ai explicitly. |
authoringMode | String | Default to gui-builder. |
wizardState | Object | Optionally preserve authoring presentation state. Default to an empty object. |
cedarSource, nlSummary | Strings | Optionally supply display source and summary. Default to empty strings. |
conflicts | Optional array of objects | Supply legacy display-only compatibility data, never authoritative validation. |
Policy recomputes validation from compileRequest.
Client conflict lists and client lifecycle states cannot bypass those checks.
Do not send status, createdBy, or another actor.
Refer to worked example for a complete create payload.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @create-policy.json \
"${POLICY_API}/policies"
Return 201 with the full policy object and policy/draft validator headers.
Save can retain incomplete work and findings. It does not guarantee submission eligibility.
Return 401 or 403 for identity or edit failures, 422 for invalid input,
or 500 for server failures.
After a timeout, list policies and check the matching policy’s detail and history before creating another policy.
PUT /policies/{policy_id}
Save, open, or restore draft work.
Require the policy_id path string and current Draft-ETag through If-Match.
Accept no query parameters.
Normal editing requires policy:edit plus an active owner/editor grant.
Rollback requires policy:rollback plus that grant.
Authorized recovery overrides remain audited.
The application/json body supports three forms:
| Form | Fields and Behavior |
|---|
| Empty object | Open a draft from the governed revision, or return the already-open draft without changing it. |
| Normal save | Require compileRequest. Optionally update readableName, wizardState, cedarSource, nlSummary, and compatibility conflicts. |
| Rollback | Require sourceVersion and nonblank reason. Confirm an existing draft with confirmDraftVersionId. |
sourceVersion is an integer governed revision number, at least one.
reason accepts 1–512 characters.
confirmDraftVersionId identifies the exact current snapshot that rollback replaces.
Obtain that identifier from the current draft summary’s currentVersionId or saved validation’s draftVersionId.
It differs from sourceVersion, which selects the governed revision to restore.
Never send compileRequest alongside sourceVersion.
Rollback restores server-held governed content into a new in-review draft.
It does not immediately replace the currently governed revision.
The body rejects unknown fields, including direct lifecycle-state changes.
Before running this normal-save example, prepare update-policy.json with the complete current compileRequest.
Use the worked payload construction
for its shape, and retain the authored fields you intend to save.
Obtain DRAFT_ETAG from a current policy read before sending the request.
curl --fail-with-body -X PUT \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${DRAFT_ETAG}" \
--data-binary @update-policy.json \
"${POLICY_API}/policies/${POLICY_ID}"
Return 200 with the full policy and latest policy/draft validators.
Saving replacement work preserves the existing governed revision and delivery.
Return the following error codes:
400 for the wrong token type.401 or 403 for authority failures.404 for missing context.409 for a changed head or illegal state.412 for persistence races.422 for invalid input.428 for a missing token.
GET /policies/{policy_id}/validation
Revalidate the exact saved draft snapshot.
Require policy:review, not merely authorship or an owner/editor grant.
Require the policy_id path string. Accept no body or query parameters.
This read requires no If-Match.
curl --fail-with-body -i -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/validation"
Return 200 with:
| Field | Type | Meaning |
|---|
policyId, draftPolicyId | Strings | Identify the policy and draft. |
draftVersionId, draftStatus, draftEtag | Integer, string, string | Identify the exact validated head and its token. |
cedarValid | Boolean | Report Cedar validation. |
compileInput, compileInputFingerprint | Object, string | Identify the saved semantic input. |
resolvedMethods | Object | Map classifications to derived, override, and effective method values. |
conflicts | Array | Return current validation findings with stable conflict identifiers. |
The Draft-ETag header identifies the same saved head.
Policy excludes archived policies from cross-policy conflict snapshots.
Return the following error codes:
401 or 403 for identity or review failures.404 without a draft.409 without a current saved snapshot or after a concurrent head change.422 for invalid saved compile input.
Server failures can return 500.
After a changed-head response, reread and review before deciding.
DELETE /policies/{policy_id}
Cancel the open draft cycle without deleting retained history.
Require policy:edit and an active owner/editor grant, or an audited recovery override.
Require the policy_id path string and current draft token through If-Match.
Accept no body or query parameters.
curl --fail-with-body -X DELETE \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "If-Match: ${DRAFT_ETAG}" \
"${POLICY_API}/policies/${POLICY_ID}"
Return 200 with the restored full policy.
An existing governed revision remains current.
Previous draft snapshots remain in history.
This operation does not archive governed protection or erase audit evidence.
Return 400, 401, 403, 404, 409, 412, or 428
for token, authority, missing-context, state, or concurrency failures.
8 - Submission, Review, Approval, and Archive Operations
Reference lifecycle decisions, exact draft preconditions, authenticated actors, and asynchronous delivery boundaries.
These application programming interface (API) commands govern saved policy work.
Use the POLICY_API base and protected POLICY_AUTH_HEADER file from
authentication.
Every operation takes a required policy_id path string and no query parameters.
Bodies use application/json and reject unknown fields.
Policy derives all actors from trusted identity.
Do not send submittedBy, approvedBy, or an archiver identity in a body.
Separate-user examples do not imply mandatory two-person enforcement.
A saved snapshot records proposal content at a particular draft head.
Submission puts that head into review. It does not establish a governed revision.
Approval creates the governed revision and queues separate publication work.
Use the policy identifier in every {policy_id} path, not draftPolicyId or a snapshot identifier.
Set POLICY_ID to that policy identifier.
Before each draft command, read the current draft and retain its exact Draft-ETag as DRAFT_ETAG.
For review decisions, use the submitted head you actually reviewed, not a pre-submission token.
For archive, retain the current policy ETag as POLICY_ETAG instead.
POST /policies/{policy_id}/submit
Submit the exact saved draft for review.
Require policy:edit and an active owner/editor policy grant.
An audited recovery authority can override the grant requirement.
Send the current Draft-ETag through If-Match.
The body is optional for clean work.
When acknowledging permitted reviewable conflicts, supply:
| Field | Type | Requirement |
|---|
reviewNotes | String | Supply 1–512 characters with nonblank trimmed text when sending a body. |
acknowledgedConflictIds | Array of strings | Include current reviewable blocking identifiers. Default to an empty array. |
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "If-Match: ${DRAFT_ETAG}" \
"${POLICY_API}/policies/${POLICY_ID}/submit"
Optional acknowledgement body:
{
"reviewNotes": "Reviewed the permitted findings and accepted their documented impact.",
"acknowledgedConflictIds": ["current-reviewable-conflict-id"]
}
Return 200 with a policy summary and updated ETag and Draft-ETag headers.
The compatibility status becomes submitted. draftState becomes in_review.
Policy checks the saved validation binding and recompiles against current catalogs.
Hard conflicts cannot receive acknowledgement.
An eligible returned draft can enter review again without an intermediate save.
Submission does not approve or publish.
Reload the submitted draft and use its new Draft-ETag for the review decision.
The token from before submission no longer identifies the current draft.
POST /policies/{policy_id}/request-changes
Return the current in-review draft to its author.
Require policy:review, not an owner/editor grant.
Send the reviewed current draft token through If-Match.
The request body contains this required reason field:
| Field | Type | Requirement |
|---|
reason | String | Supply 1–512 characters with nonblank trimmed text. |
The current request schema enforces this reason length.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${DRAFT_ETAG}" \
--data '{"reason":"Narrow the resource scope before approval."}' \
"${POLICY_API}/policies/${POLICY_ID}/request-changes"
Return 200 with the new draft summary:
{
"draft": {
"policyId": "policy-1",
"draftPolicyId": "draft-1",
"cycleNumber": 1,
"proposedRevisionNumber": 1,
"currentVersionId": 43,
"draftStatus": "changes_requested",
"etag": "W/\"draft-1.1.43\""
}
}
Use the returned draft.etag for subsequent draft work.
Policy preserves authored content and records the reviewer’s decision.
An existing governed revision remains current.
POST /policies/{policy_id}/approve
Approve the exact reviewed in-review draft.
Require policy:approve. Policy ownership alone does not grant approval.
Send its current Draft-ETag through If-Match.
Do not reuse the author’s token from before submission.
The required approval body accepts these review notes and conflict identifiers:
| Field | Type | Requirement |
|---|
reviewNotes | String | Supply required review notes for every approval: 1–512 characters with nonblank trimmed text. |
acknowledgedConflictIds | Array of strings | Supply permitted current conflict identifiers. Default to an empty array. |
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${DRAFT_ETAG}" \
--data '{"reviewNotes":"Reviewed current intent and validation.","acknowledgedConflictIds":[]}' \
"${POLICY_API}/policies/${POLICY_ID}/approve"
Return 200 with a policy summary, policy ETag, and current draft validator where applicable.
Relevant response fields include:
{
"policy": {
"id": "policy-1",
"status": "approved",
"policyState": "approved",
"governedRevision": 1,
"hasOpenDraft": false,
"draftState": null
}
}
Policy revalidates dependencies before creating the governed revision.
Changed or unacknowledged findings can block approval.
Approval queues durable asynchronous publication.
It does not prove publication, consumer receipt, or downstream protection.
Inspect the independent enforcementState and
operation evidence.
Operation inspection requires policy:audit. Approval capability alone does not grant that access.
POST /policies/{policy_id}/archive
Request removal of the approved policy’s published configuration.
Use GET /policies/{policy_id}/operations to monitor that background removal.
Confirm that the policy has a governed revision before selecting archive.
Draft cancellation is a separate operation and does not withdraw governed protection.
Require policy:archive.
Send the latest policy ETag through If-Match, never the draft token.
The archive request accepts this reason field:
| Field | Type | Requirement |
|---|
reason | String | Supply 1–512 characters with nonblank trimmed text. |
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${POLICY_ETAG}" \
--data '{"reason":"Approved retirement of the governed policy."}' \
"${POLICY_API}/policies/${POLICY_ID}/archive"
Return 200 with a policy summary, deploymentId, and integer generation.
The summary identifies the independent archiving protection state.
Do not interpret the compatibility archive status as completed withdrawal.
Record the returned generation for subsequent
archive evidence
or authorized retry.
Use deploymentId to select the operation and generation to distinguish its work from later attempts.
Response Codes and Concurrency
The table lists possible failure status codes for each lifecycle operation:
| Operation | Failure Statuses |
|---|
| Submit | Return 400, 401, 403, 404, 409, 412, 422, 428, or 500. |
| Request changes | Return 401, 403, 404, 409, 422, or 428. |
| Approve | Return 400, 401, 403, 404, 409, 412, 422, 428, or 500. |
| Archive | Return 400, 401, 403, 404, 409, 412, 422, 428, or 500. |
401 identifies missing trusted identity. 403 identifies missing authority.
404 identifies missing policy or draft context.
428 identifies a missing required token.
Draft commands normally return 409 for a changed head.
Request-changes also returns 409 when the head is not in review.
Submit and approve return 400 for a non-draft token.
Concurrent policy/revision persistence can produce 412.
Archive returns 400 for malformed policy tokens and 412 for stale versions.
409 can also mean invalid lifecycle state, blocking conflicts, or changed dependencies.
422 can contain body-schema errors or sanitized validation findings.
Compile, submit, and approval validation failures can expose a supportReference.
Refer to error handling for envelope variations.
These commands do not implement a general Idempotency-Key contract.
After a timeout, inspect current policy and history before deciding whether to repeat.
After a conflict, review changed evidence before issuing another command.
Do not apply a fresh token to an old, unreviewed decision.
9 - History and Policy Access Operations
Reference policy grants, legacy versions, bounded lifecycle history, and restricted audit exports.
These application programming interface (API) operations read policy history and manage owner/editor access.
Use the configured POLICY_API and protected POLICY_AUTH_HEADER file from
authentication.
Every operation requires the policy_id path string.
Set POLICY_ID to the intended policy identifier before running the examples.
None uses a general If-Match or Idempotency-Key contract.
A policy grant provides owner/editor access to that policy.
It does not create command capabilities such as review, approval, or audit.
History distinguishes draft saves, approvals, background recompilation, and delivery requests.
GET /policies/{policy_id}/access-grants
Require policy:view and accept no body.
The optional boolean active_only query parameter defaults to true.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/access-grants?active_only=true"
Return 200 with {"grants":[...]}.
Each grant has integer id, policyId, subjectType, subjectId, accessLevel,
grantedBy, grantedAt, nullable revokedBy, and nullable revokedAt.
subjectType uses user or role. accessLevel uses owner or editor.
An empty result does not independently establish policy existence.
Identity or capability failures return 401 or 403. Invalid query values return 422.
POST /policies/{policy_id}/access-grants
Require active policy ownership or an authorized audited recovery override.
An editor grant does not authorize grant management.
Creation never grants approval or review capability.
The application/json body rejects extra fields:
| Field | Type | Requirement |
|---|
subjectType | String | Select user or role. |
subjectId | String | Supply the exact verified login username or gateway-forwarded authority described below, 1–255 characters. |
accessLevel | String | Select owner or editor. |
For subjectType: user, use the recipient’s exact gateway-verified login username.
For subjectType: role, use an authority the gateway actually forwards for the intended accounts.
This authority can be a permission name, rather than a role name.
Do not substitute a Protegrity Provisioned Cluster (PPC) opaque account or role identifier, display name, or authoring-catalog runtime principal.
Ask a PPC user with administrator permissions to confirm the relevant identity mapping.
Never supply or spoof gateway identity headers.
Replace the example username alex with the intended recipient’s verified login username before running this request:
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data '{"subjectType":"user","subjectId":"alex","accessLevel":"editor"}' \
"${POLICY_API}/policies/${POLICY_ID}/access-grants"
Return 201 with the grant object described above.
Policy derives grantedBy from trusted identity.
Creation and listing confirm grant persistence, not the recipient’s effective access.
Policy matches user subjects to verified usernames and role subjects to forwarded authorities.
It does not translate PPC account or role identifiers into these values.
During an approved handoff, have the recipient confirm intended access through the supported workflow using their own authenticated account.
Keep command capabilities separate from owner/editor grants.
Return 401 or 403 for identity or ownership failures, 404 for an unknown policy,
409 for duplicate grants or noneditable policies, or 422 for malformed bodies.
Display-only imported policies cannot receive grants.
After a timeout, list existing grants before repeating creation.
DELETE /policies/{policy_id}/access-grants/{grant_id}
Revoke an active grant without erasing its history.
Require active ownership or an authorized audited recovery override.
The required grant_id path parameter uses an integer.
Accept no body or query parameters.
Set GRANT_ID to the integer id returned when listing the intended grant.
Do not substitute its subject identifier.
curl --fail-with-body -X DELETE \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/access-grants/${GRANT_ID}"
Return 200 with the grant object, including revoker and revocation time.
Return 401 or 403 for identity or ownership failures.
Return 404 for an unknown grant, or 409 when revocation would remove the last active owner.
Invalid path values return 422.
List grants with active_only=false to check the revoked grant and its revocation time.
If this is the last active owner, grant ownership to the intended replacement user first.
Confirm the new active grant and the replacement’s intended ownership access before retrying revocation.
Have the replacement use their own authenticated account through the approved ownership-management workflow.
Do not remove the previous owner’s access based only on a saved grant.
GET /policies/{policy_id}/versions
Inspect the compatibility version chain.
Accept no body, query parameters, or additional command capability.
Gateway access rules still apply.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/versions"
Return 200 with an oldest-first array of full policy objects.
Each object includes id, version, status, and authored policy fields.
These versions do not replace governed revision or draft snapshot identifiers.
Return 404 when no policy versions exist.
Gateway failures can return 401 or 403.
GET /policies/{policy_id}/history
Read newest-first lifecycle activity without a mutation body.
The backend permits optional identity for this compatibility read.
Gateway access rules still apply.
Reasons require policy:audit or policy:review. Other readers receive redacted reasons.
The following table describes the supported history pagination parameters:
| Query Parameter | Type | Requirement |
|---|
limit | Integer | Optionally select 1–100 entries. Otherwise use the bounded default window. |
offset | Integer | Optionally select a nonnegative offset. Start at zero. |
curl --fail-with-body -i -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/history?limit=20&offset=0"
Return 200 with an array of history entries.
Use X-History-Truncated and X-Next-Offset to continue a truncated page.
The default window contains at most 100 entries.
When the response indicates truncation, request the returned X-Next-Offset with the same limit.
Read subsequent pages before treating the history as complete.
The following table summarizes fields returned in each history entry:
| Response Fields | Meaning |
|---|
versionNumber, status, action, actor, timestamp | Identify compatibility version and attributable activity. |
historySource, reason, reasonRedacted | Distinguish legacy, draft, or protection entries and restricted notes. |
revisionId, draftVersionId, proposedRevisionNumber | Identify exact governed or draft lineage. |
governedRevisionNumber, minorVersion, sourceRevisionNumber | Identify approved revisions, compilation minors, and rollback sources. |
deploymentId, deploymentGeneration | Identify publication or withdrawal lineage. |
priorEnforcementState, enforcementState | Describe independent protection transitions. |
isCurrent, isGoverned, isSuperseded, isClosed | Distinguish current and retained historical entries. |
Fields can contain null values when they do not apply to that event.
Use draftVersionId for a saved snapshot, revisionId for governed identity, and governedRevisionNumber for its major revision number.
A minorVersion identifies compiled output within a governed revision.
Do not substitute compatibility versionNumber for these lineage fields.
Automatic recompilation can add compilation minors without changing author intent.
Do not attribute system compilation events to another human approval.
Return 404 for an unknown policy and 422 for invalid pagination.
Gateway failures can return 401 or 403.
GET /policies/{policy_id}/audit-export
Require policy:audit and accept no body.
Use the same optional limit range and nonnegative offset as history.
The default window remains bounded to 100 entries.
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/audit-export?limit=20&offset=0"
Return 200 with an array of compliance records.
Records include policyId, revisionNumber, minorVersion,
sourceLegacyVersionNumber, sourceRevision, action, actor, reason, and timestamp.
Where applicable, records also include artifactFingerprint, deploymentGeneration,
deploymentFingerprint, deploymentId, priorEnforcementState, and enforcementState.
Governed records can include principals, classifications, enforcement decisions, and protection actions.
The export does not return compiled artifact payloads.
It does not export the entire historical legacy version chain.
The export includes draft snapshots, governed revisions, cancellation, and retained lifecycle evidence.
It retains original actor attribution and reasons when available.
Return 401 or 403 for identity or audit failures, 404 for an unknown policy,
or 422 for invalid pagination.
Inspect target-specific evidence separately. An audit record does not certify activation.
10 - Product Retrieval and Compatibility Deployment
Reference consumer output retrieval and distinguish compatibility deployment from governed publication.
Approval queues asynchronous governed publication.
Consumer retrieval, publication, and target activation establish different evidence.
Use the application programming interface (API) base and protected POLICY_AUTH_HEADER file from
authentication.
Publication makes compiled output available to its target.
Consumer receipt records retrieval. Activation means the target uses that output.
Approval alone establishes none of these completion conditions.
GET /product-policies/{product_type}
Retrieve the latest published Federated Guardrails aggregate.
The current public product_type enum accepts only federated-guardrails.
Do not substitute pim or securequery.
Accept no body.
Optional environment and product_id query strings are reserved and currently ignored.
They do not select separate consumer output.
Send the following headers when retrieving published consumer output:
| Header | Requirement |
|---|
Authorization | Authenticate through the gateway according to deployment access rules. |
If-None-Match | Optionally send the cached product ETag. |
curl --fail-with-body -i \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/product-policies/federated-guardrails"
Return 200 with ETag, Last-Modified, and Cache-Control headers.
The response contains:
| Field | Type | Meaning |
|---|
product_id | String | Identify federated-guardrails. |
updated_at | Timestamp | Identify the stored output update. |
revision | Integer | Identify the global append-only output revision. |
version | Integer | Identify the product’s monotonic output version. |
fingerprint | String | Identify the combination of policy versions and compilation minors included in this output. |
content | Object | Carry native entities, policies, and target content. |
Illustrative response:
{
"product_id": "federated-guardrails",
"updated_at": "2026-10-29T12:00:00Z",
"revision": 15,
"version": 4,
"fingerprint": "example-lineage-fingerprint",
"content": {
"entities": [],
"warnings": [],
"policies": {
"templates": {},
"staticPolicies": {},
"templateLinks": []
}
}
}
A matching If-None-Match condition returns 304 with no body.
The response supplies Last-Modified, but this operation does not evaluate If-Modified-Since.
The fingerprint identifies contributing policy versions, rather than only comparing generated text.
Background recompilation can change those versions without another human approval.
The product revision and version identify aggregate output, not one policy’s governed revision.
Use policy history to find an individual policy’s approved version and compilation minor.
Return 404 when no published output exists.
Return 422 for an unsupported product type.
Gateway identity and access failures can return 401 or 403.
Guardrails Receipt Boundary
When GUARDRAILS_CONSUMER_USERNAME is nonempty, only the exact trusted consumer
identity records receipt evidence.
The setting does not authenticate callers.
The empty-string default accepts only requests with absent or empty identity, for anonymous compatibility.
Named requests do not qualify under this default.
Qualifying 200 and 304 responses can both record evidence.
With a nonempty setting, anonymous reads and diagnostics under another identity do not qualify.
Receipt does not prove activation or receipt by every target replica.
A qualifying consumer retrieval records receipt. No separate acknowledgement request is required.
Successful retrieval alone does not establish eligibility.
The receipt must match current publication targets and checksums, or exact current contributor lineage in a newer aggregate.
Publication reaches Published. Publication plus qualifying receipt allows reconciliation to Enforced for Guardrails-only policies.
Mixed policies also require Data protection evidence.
Use Guardrails monitoring to check whether the consumer applies the retrieved configuration.
The chart maps apiService.environment.GUARDRAILS_CONSUMER_USERNAME through the API ConfigMap into the environment.
Refer to Guardrails consumer evidence.
The setting does not change gateway access rules.
POST /policies/{policy_id}/deploy
Retain this compatibility operation for eligible legacy approved policies.
Do not use it to force publication of a governed revision.
Governed delivery belongs to approval and background processing.
The server rejects this operation when governed publication owns delivery.
Require policy:approve and a trusted caller identity.
Policy forwards the caller’s bearer credential for request-driven Policy Integration Manager (PIM) writes.
That caller also needs the applicable PIM permissions.
Policy accepts the gateway’s deployment cookie fallback when no explicit authorization header exists.
Do not send identity-forwarding headers or an actor in the body.
The route accepts the following path and query parameters:
| Parameter | Type | Requirement |
|---|
policy_id | Path string | Identify the eligible approved policy. |
reuse_existing | Query boolean | Default to true. Inspect existing native inventory for reuse. |
This route does not require If-Match or a general Idempotency-Key.
The body uses application/json.
It extends the public compile request with these optional fields:
| Field | Type | Meaning |
|---|
pimBindings | Object | Map selected symbolic references to existing native UID strings. |
pimReconciliationReason | String | Explain explicit binding selections. Allow at most 512 characters. |
federated-guardrails | Object | Supply compile and optional native Guardrails rules or permission matrix. |
pimBindings requires an audit reason and cannot replace an existing ownership binding.
Refer to reconciliation for governed ownership incidents.
The public deployment schema does not accept a Secure Query-native variant.
Use the deployed /doc document for the complete nested compile and native rule schemas.
Before running this compatibility-only request, prepare and review the complete deploy-request.json file.
Set POLICY_ID to the eligible legacy policy’s identifier.
Use the compile-body reference
for its base fields and the additional deployment fields listed above.
Do not pass the outer create-policy envelope from the worked lifecycle.
curl --fail-with-body -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @deploy-request.json \
"${POLICY_API}/policies/${POLICY_ID}/deploy?reuse_existing=true"
Return 200 with plan, result, and nullable reconciliation.
The last field can contain protected, unprotected, awaiting_protection,
and unreadable resource-identifier arrays.
These arrays report observed resource states, not confirmation that every intended target applies the configuration.
The following table summarizes compatibility deployment status codes and their meanings:
| Status | Meaning |
|---|
400, 422 | Reject invalid request fields, compile input, or binding selections. |
401, 403 | Reject identity, approval capability, or target authorization. |
404 | Reject an unknown policy. |
409 | Reject ineligible lifecycle state, governed delivery ownership, or a native-reference mismatch. |
502 | Report a non-authentication target rejection. |
503 | Report target unavailability or unavailable deployment configuration. |
500 | Report a server or post-target persistence failure. |
If the request times out, check policy detail and ask the PIM administrator whether the affected objects changed.
Do not repeat deployment until the administrator checks for a partially applied request.
11 - Authoring Schema Operations
Reference the request, response, and failure contracts for this operation family.
Use the configured POLICY_API base and protected POLICY_AUTH_HEADER file from
authentication.
All paths below are relative to that base.
Examples read the bearer header from that file. Keep request payloads and logs free of credentials.
Consult your deployed /doc document for complete nested schemas.
Response examples illustrate relevant fields rather than every optional property.
These application programming interface (API) reads return 200 with schema vocabulary.
They accept no request body and do not save or approve a policy.
Gateway access rules apply. These reads do not require a separate command capability.
Policy Integration Manager (PIM) owns the Data target vocabulary.
Cedar is the policy language whose schema defines entity types, attributes, and actions.
Schema responses describe allowed types and actions. They do not list discovered users, groups, or data locations.
Use /catalog/principals and /catalog/resources to obtain the identifiers needed by compile requests.
For actions, use the vocabulary required by that request field rather than copying a display label from another endpoint.
GET /schema/cedar
Retrieve Cedar schema used by Policy.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/schema/cedar"
- Response
- Cedar schema payload.
Sample response:
{
"filename": "protegrity.cedarschema",
"namespaces": ["Protegrity"],
"source": "namespace Protegrity { ... }"
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /schema/actions
Retrieve the schema-sourced action vocabulary grouped by enforcement point.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/schema/actions"
- Response
SchemaActionCatalog, grouped by enforcement point.
Each group identifies its actual Cedar namespace and declared action identifiers.
The federated and data-protection groups expose different native vocabularies.
Sample response:
{
"enforcement_points": {
"federated": {
"enforcement_point": "federated",
"namespace": "FederatedGuardrails",
"actions": []
},
"data-protection": {
"enforcement_point": "data-protection",
"namespace": "PIM",
"actions": []
}
}
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /schema/authoring-actions
Retrieve the abstract vocabulary accepted within /policies/compile, filtered by enforcement point.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/schema/authoring-actions"
- Response
AuthoringActionCatalog, grouped by enforcement point.
Data authoring includes viewNull for explicit null-read permission.
The federated group returns an empty abstract-action list.
Use its native matrix and the FEDX variant of /policies/preview instead.
Here, FEDX is the API selector for Federated Guardrails, not a separate product.
An empty abstract-action list does not mean that target has no native actions.
An empty Data actions array does not request null-read permission. Select viewNull explicitly.
Sample response:
{
"enforcement_points": {
"federated": {
"enforcement_point": "federated",
"actions": []
},
"data-protection": {
"enforcement_point": "data-protection",
"actions": ["viewNull", "viewCleartext", "viewProtected", "protect", "reprotect"]
}
}
}
Error codes:
Possible error codes are 401, 403, and 500.
GET /schema/attributes
Retrieve schema-sourced attribute-based access control (ABAC) and row-level security (RLS) attributes.
- Path parameters
- None.
- Request body
- None.
- Request parameters
- None.
Sample request:
curl --fail-with-body -H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/schema/attributes"
- Response
- Attribute catalog for principal, resource, and context conditions.
Sample response:
{
"principals": {
"Role": [
{
"path": "principal.name",
"label": "Name",
"type": "String",
"optional": false,
"is_set": false,
"enum_values": []
}
]
},
"resource": [],
"context": [],
"enums": {}
}
Error codes:
Possible error codes are 401, 403, and 500.
12 - Recovery and Ownership Reconciliation
Reference nine operations for restricted diagnostics, retained delivery recovery, archive evidence, and native ownership reconciliation.
These application programming interface (API) operations support authorized recovery.
They do not replace authoring, review, or target-specific protection checks.
Policy Integration Manager (PIM) ownership mappings connect reference keys to native unique identifiers (UIDs).
A saved mapping does not prove that its native resource still exists.
Use the POLICY_API base and protected POLICY_AUTH_HEADER file from
authentication.
Every path below is relative to POLICY_API.
Set POLICY_ID to the affected policy identifier for policy-specific requests.
For retry, obtain DEPLOYMENT_ID from the operation-list response.
For reconciliation, copy identifiers and versions from the inspection response before constructing a decision body.
For symptom-based instructions, use the
recovery playbooks.
For changed compilation inputs, see
automatic recompilation.
Retained deployment retry does not request recompilation.
A deployment generation identifies a publication or removal request. That request can have several retry attempts.
Retry sends the configuration already saved for that request.
Reconciliation changes which PIM object Policy associates with a saved reference.
Automatic recompilation instead generates updated configuration from already approved policy inputs.
Authority and Preconditions
The table maps each recovery operation to its required capability:
| Operation | Required Capability |
|---|
| Read operations or validation diagnostics | Require policy:audit |
| Retry publication | Require policy:approve |
| Retry withdrawal or record archive evidence | Require policy:archive |
| Inspect or decide ownership reconciliation | Require policy:system-configure |
Select withdraw_policy | Require both policy:system-configure and policy:archive |
These endpoints do not require an owner/editor grant.
Such grants do not supply the command capabilities above.
Policy derives decision actors from authenticated identity, not request-body fields.
A support reference does not grant diagnostic access.
Authors without these capabilities should retain safe evidence for authorized operators.
The following table summarizes the validator or control used for each recovery task:
| Token or Control | Scope and Rule |
|---|
Draft-ETag | Pin draft commands. Never substitute it for ownership evidence. |
Policy ETag | Pin ordinary archive initiation. Do not use it for reconciliation. |
Registry ETag | Pin reconciliation decisions and later binding-enumeration pages. |
governedSetGeneration | Copy this policy-set version from inspection. Policy rejects it if relevant approved policies change before the decision. |
Idempotency-Key | Supply 1–128 characters for either reconciliation decision endpoint. |
Reconciliation decisions require one strong registry token through If-Match.
An entity tag (ETag) validates inspected registry state. The governed-set generation tracks policy-set changes separately.
Preserve the exact quoted value returned by inspection.
Do not construct a token from ownershipVersion, or use a weak draft token.
Use a new decision key for changed evidence.
Reuse a key only with identical evidence and the same authenticated actor.
Retain the inspection response’s exact ETag as REGISTRY_ETAG.
Set DECISION_KEY to a new 1–128-character key for the specific inspected decision.
Missing registry preconditions return 428. Malformed tokens return 400.
Stale registry evidence returns 412.
Changed governed generations, illegal decisions, or changed decision-key content return 409.
Malformed decision bodies or missing/invalid decision keys return 422.
Repeat inspection after 409 or 412, compare the changed policies and mappings, then prepare a new decision if needed.
GET /policies/{policy_id}/operations
Read deployment generations and their retained publication or withdrawal work.
The request uses this path parameter:
| Parameter | Type | Requirement |
|---|
policy_id | Path string | Identify the policy whose operations you need. |
Require policy:audit. Accept no request body, query parameters, or conditional headers.
Return 200 with a top-level array, not an operations envelope.
Each entry includes:
| Response Field | Type | Meaning |
|---|
deploymentId, generation, operation | String, integer, string | Identify the deployment generation and publication or withdrawal operation. |
enforcementState, requestedAt | String, timestamp | Describe protection progress and request time. |
retryable, attemptCount | Boolean, integer | Indicate advisory eligibility and latest event attempts. |
lastError | Nullable string | Describe retained failure text for unprocessed work. |
issueCategory, severity | Nullable strings | Classify the projected issue. Severity uses warning or error. |
requiresOperatorAction, detectedAt | Boolean, nullable timestamp | Identify operator intervention and issue detection. |
replacedByGeneration | Nullable integer | Identify a successful successor when applicable. |
diagnostics | Array of objects | Retain sanitized publication diagnostics. |
Diagnostics contain supportReference, code, message, remediation, and
detectedAt, with retryable and requiresOperatorAction.
They can also include operationId, statusCode, resourceReference, and
details containing path, constraint, and message.
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/operations"
Illustrative successful response:
[
{
"deploymentId": "deployment-7",
"generation": 7,
"operation": "publish",
"enforcementState": "publishing",
"requestedAt": "2026-10-29T12:00:00Z",
"retryable": true,
"attemptCount": 4,
"lastError": "Target temporarily unavailable",
"issueCategory": null,
"severity": null,
"requiresOperatorAction": false,
"detectedAt": null,
"replacedByGeneration": null,
"diagnostics": []
}
]
Return 401 without trusted identity, or 403 without audit capability.
Return 404 with no lifecycle operations for policy when no deployments exist.
That response does not establish whether the policy exists.
The retryable hint considers diagnostics and successor generations.
If diagnostics say retry cannot help, resolve the named problem before submitting the retry command.
Reading operations does not restart them.
Use the selected entry’s deploymentId in the retry path.
Do not substitute its integer generation, a policy revision, or a draft snapshot identifier.
GET /validation-diagnostics/{support_reference}
Retrieve restricted evidence from a compile, submit, or approval validation failure.
The request uses this path parameter to select the diagnostic evidence:
| Parameter | Type | Requirement |
|---|
support_reference | Path string | Copy the exact supportReference from the failure response. |
Require policy:audit. Accept no body, query parameters, or conditional headers.
Return 200 with the diagnostic object and Cache-Control: no-store.
curl --fail-with-body \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/validation-diagnostics/${SUPPORT_REFERENCE}"
{
"supportReference": "VAL-example",
"code": "approval_validation_failed",
"message": "Policy command validation failed.",
"remediation": "Review the indicated configuration constraints before retrying.",
"detectedAt": "2026-10-29T12:00:00Z",
"details": [
{
"path": "$.user_attribute",
"constraint": "required",
"message": "Set the identity source user attribute."
}
]
}
The shared diagnostic shape can also include nullable operationId,
statusCode, and resourceReference fields.
Return 401 without trusted identity, or 403 without audit capability.
Return 404 when evidence does not exist or its seven-day retention expires.
Preserve the original failure, timestamp, and reference before expiration.
Do not send credentials, raw identity attributes, or sensitive payloads during escalation.
Diagnostic retrieval does not repair the configuration or validate another draft head.
POST /policies/{policy_id}/deployments/{deployment_id}/retry
Reset eligible terminal work within an existing deployment generation.
Policy reuses retained artifacts. It does not compile a corrected draft.
The retry request uses these path parameters:
| Parameter | Type | Requirement |
|---|
policy_id | Path string | Identify the policy. |
deployment_id | Path string | Select its retained generation from archive results or operation inspection. |
Require policy:approve for publication, or policy:archive for withdrawal.
Accept no body or query parameters.
This operation requires neither If-Match nor Idempotency-Key.
curl --fail-with-body -i -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/policies/${POLICY_ID}/deployments/${DEPLOYMENT_ID}/retry"
The following table summarizes retry response status codes:
| Status | Meaning |
|---|
204 | Confirm the terminal-work reset. Return an empty body. |
401, 403 | Reject missing identity or the operation-specific capability. |
404 | Reject an unknown deployment or one belonging to another policy. |
409 | Reject replaced work, any newer generation, or work without a retryable terminal event. |
Correct the underlying condition before retrying.
A newer in-progress generation also prevents retrying its predecessor.
Repeated retry requests need not return 204. The first reset can remove terminal eligibility.
After a timeout, inspect operations before deciding whether another request makes sense.
A successful reset does not prove publication, withdrawal, or protection recovery.
An auditor must read subsequent operation progress. Verify target evidence separately.
If you can retry but lack policy:audit, arrange that progress check with an authorized auditor.
POST /policies/{policy_id}/archive-evidence
Record an immutable manual evidence event for an active withdrawal.
This event does not replace observed deprotection.
Require policy:archive. Identify policy_id through the path.
Accept the following application/json body, with no extra fields.
This operation requires neither If-Match nor Idempotency-Key.
The request body accepts the following evidence fields:
| Field | Type | Requirement |
|---|
deploymentId | String | Identify the active withdrawal deployment for this policy. |
ticketReference | String | Supply 1–128 characters. Retain nonblank text after trimming. |
description | String | Supply 1–512 characters. Retain nonblank text after trimming. |
locationIds | Array of strings | Supply at least one distinct, nonblank expected location identifier. |
Prepare archive-evidence.json with the active deployment and verified expected locations:
{
"deploymentId": "withdrawal-8",
"ticketReference": "CHANGE-204",
"description": "Completed the approved manual withdrawal check for this location.",
"locationIds": ["location-17"]
}
Replace the illustrative identifiers with your verified values before submitting the file.
curl --fail-with-body -i -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
--data-binary @archive-evidence.json \
"${POLICY_API}/policies/${POLICY_ID}/archive-evidence"
Return 201 with only the event identifier and recording timestamp:
{
"eventId": "event-38",
"recordedAt": "2026-10-29T12:30:00Z"
}
Return 401 or 403 for identity or capability failures.
Return 404 for an unknown policy draft identity or an unrelated/unknown deployment.
Return 409 for an inactive withdrawal.
Unexpected locations return 409 with detail.message and detail.unexpectedLocationIds.
Malformed or duplicate location identifiers return 422.
Capture the deployment from archive initiation or an authorized operations read.
Confirm expected locations with your authorized withdrawal operator before recording evidence.
This API does not expose a complete location-discovery operation.
Stop if you cannot establish that scope. Do not guess identifiers.
Repeated accepted submissions can record additional events rather than deduplicate automatically.
Check authorized history or audit export after an uncertain result.
A 201 records the claim, not completed withdrawal or removal of protection.
GET /policies/{policy_id}/pim-reconciliations
Inspect ownership evidence for a policy’s current governed publication.
Require policy:system-configure. Accept no body or conditional header.
The request uses this path parameter:
| Parameter | Type | Requirement |
|---|
policy_id | Path string | Identify the affected policy. |
refKey | Optional query string | Select one nonempty reference key used by its governed plan. |
Set REF_KEY to an exact reference key from the policy’s unresolved bindings.
If you do not have one, first call this route without the refKey query parameter to list those bindings.
curl --fail-with-body -i --get \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
--data-urlencode "refKey=${REF_KEY}" \
"${POLICY_API}/policies/${POLICY_ID}/pim-reconciliations"
Return 200 and a strong registry ETag.
Without refKey, return an incident envelope containing policyId,
ownershipVersion, governedSetGeneration, and bindings.
The array contains unresolved bindings, not every healthy mapping.
With refKey, return one binding directly:
{
"policyId": "policy-1",
"revisionId": 15,
"deploymentId": "deployment-7",
"generation": 7,
"refKey": "dataelement:customer__EMAIL",
"resourceKind": "data_element",
"persistedUid": "58",
"status": "missing",
"candidates": [],
"allowedActions": ["authorize_replacement", "withdraw_policy"],
"affectedPolicies": [
{
"policyId": "policy-1",
"revisionId": 15,
"revisionNumber": 3,
"deploymentId": "deployment-7",
"generation": 7,
"enforcementState": "publishing",
"affectedNativeRefs": ["dataelement:customer__EMAIL"],
"affectedNativeOperations": ["createDataElement"]
}
],
"ownershipVersion": 7,
"governedSetGeneration": 4
}
Each binding has resourceKind equal to data_element or source.
Its status uses healthy, missing, or replacement_authorized.
Each candidate includes uid, name, compatible, and a definition object.
Only allowedActions describes currently permissible decision choices.
The affectedPolicies array identifies shared impact and exact revision lineage.
Omit refKey to discover unresolved bindings before selecting one for detailed inspection.
A refKey names a symbolic ownership mapping. persistedUid identifies its native resource.
Do not substitute one for the other or derive them from display names.
Return 401 or 403 for identity or capability failures.
Return 404 for a missing binding, missing registry, or a reference outside the governed plan.
Return 409 without a current governed publication, or after a concurrent governed-set change.
Return 422 for malformed query values.
Return 503 when Policy cannot obtain complete native inventory.
An inventory failure never proves native absence.
Preserve the returned registry header and generation alongside reviewed candidate evidence.
POST /policies/{policy_id}/pim-reconciliations
Apply one inspected ownership decision.
Require policy:system-configure. Additionally require policy:archive for withdrawal.
Identify policy_id through the path. Accept no query parameters.
Require If-Match with the inspected registry token and an Idempotency-Key.
All body variants use application/json and reject extra fields.
The following table lists fields required by every reconciliation decision:
| Common Field | Type | Requirement |
|---|
action | String | Select an inspected allowed action below. |
refKey | String | Identify the nonblank inspected binding. |
reason | String | Supply 1–512 characters with nonblank trimmed text. |
governedSetGeneration | Integer | Supply the inspected generation, at least one. |
The following table lists each allowed decision and its additional required fields:
| Action | Additional Required Fields | Meaning |
|---|
adopt_candidate | Supply candidateUid, affectedPolicyIds, and affectedPolicyRevisions. | Adopt the selected compatible native candidate. |
authorize_replacement | Supply impactAcknowledged, affectedPolicyIds, and affectedPolicyRevisions. | Authorize replacement after accepting affected-policy impact. |
withdraw_policy | Supply integer policyVersion, at least one. | Start governed withdrawal using the current policy version. |
Supply a nonempty string for candidateUid.
Supply nonempty affected-policy arrays and revision maps for adoption or replacement.
Map policy identifiers to inspected revisionId values, not revisionNumber values.
Include the exact complete affected set.
Replacement requires impactAcknowledged: true. False does not authorize impact.
For withdrawal, obtain policyVersion from a current policy read.
Keep the registry token in If-Match. Do not replace it with the policy token.
Prepare reconciliation-decision.json with one complete decision variant.
Use the replacement, adoption, or withdrawal payload below only when current inspection permits that action.
curl --fail-with-body -i -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${REGISTRY_ETAG}" \
-H "Idempotency-Key: ${DECISION_KEY}" \
--data-binary @reconciliation-decision.json \
"${POLICY_API}/policies/${POLICY_ID}/pim-reconciliations"
Replacement example reconciliation-decision.json:
{
"action": "authorize_replacement",
"refKey": "dataelement:customer__EMAIL",
"reason": "Reviewed shared impact after confirmed native deletion.",
"governedSetGeneration": 4,
"impactAcknowledged": true,
"affectedPolicyIds": ["policy-1"],
"affectedPolicyRevisions": {"policy-1": 15}
}
Adoption variant:
{
"action": "adopt_candidate",
"refKey": "dataelement:customer__EMAIL",
"reason": "Reviewed the compatible candidate and shared policy lineage.",
"governedSetGeneration": 4,
"candidateUid": "61",
"affectedPolicyIds": ["policy-1"],
"affectedPolicyRevisions": {"policy-1": 15}
}
Withdrawal variant:
{
"action": "withdraw_policy",
"refKey": "dataelement:customer__EMAIL",
"reason": "Approved withdrawal instead of replacing this binding.",
"governedSetGeneration": 4,
"policyVersion": 9
}
These variants illustrate alternative inspected situations.
Do not submit adoption when inspection returns no compatible candidate.
Return 200 for adoption or replacement, with a registry ETag:
{
"action": "authorize_replacement",
"refKey": "dataelement:customer__EMAIL",
"affectedPolicyIds": ["policy-1"],
"affectedPolicyRevisions": {"policy-1": 15},
"governedSetGeneration": 4,
"ownershipVersion": 8,
"reconciliationId": "decision-204",
"status": "authorized"
}
Adoption returns the same shape with action: "adopt_candidate" and status: "completed".
Replacement authorization does not mean Policy already created a replacement resource.
Withdrawal returns 202 and a registry ETag:
{
"action": "withdraw_policy",
"refKey": "dataelement:customer__EMAIL",
"ownershipVersion": 7,
"status": "withdrawal_started",
"deploymentId": "withdrawal-8",
"generation": 8,
"remainingAffectedPolicyIds": []
}
Return 401 or 403 for identity or required capability failures.
Return 404 for missing or unrelated bindings.
Return 409 for incompatible candidates, changed affected lineage, invalid actions,
changed generations, or reused keys with different decision content.
Return 503 when complete inventory is unavailable.
The shared 400, 412, 422, and 428 precondition rules also apply.
An identical accepted decision can replay without another ownership transition.
Preserve its original evidence and key after an uncertain response.
Do not change its actor, reason, action, or affected set while reusing the key.
Reinspect the binding after success. Inspect operation progress after withdrawal acceptance.
Neither 200 nor 202 proves target publication or completed withdrawal.
GET /pim-reconciliations/bindings
Enumerate saved reference-to-UID mappings without querying native inventory.
Require policy:system-configure. Accept no body.
The request uses these pagination parameters:
| Parameter | Type | Requirement |
|---|
limit | Query integer | Select 1–100 bindings. Default to 100. |
offset | Query integer | Select a nonnegative offset. Default to zero. |
If-Match | Conditional header | Supply the first page’s registry token on every page after offset zero. |
curl --fail-with-body -i \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
"${POLICY_API}/pim-reconciliations/bindings?limit=1&offset=0"
Return 200, the registry ETag, and Cache-Control: no-store:
{
"target": "https://pim.example.test",
"ownershipVersion": 7,
"bindings": [{"refKey": "dataelement:customer__EMAIL", "persistedUid": "58"}],
"total": 2,
"limit": 1,
"offset": 0,
"nextOffset": 1
}
Bindings follow reference-key order.
The final page returns nextOffset: null.
Use each returned nextOffset for the next request while retaining the first page’s exact registry token.
Keep one registry version throughout enumeration:
curl --fail-with-body -i \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "If-Match: ${REGISTRY_ETAG}" \
"${POLICY_API}/pim-reconciliations/bindings?limit=1&offset=1"
Return 401 or 403 for identity or capability failures.
Return 404 when the registry does not exist.
Return 400 for malformed tokens, 412 for a moved registry,
428 for missing later-page tokens, or 422 for invalid pagination.
On 412, restart from offset zero instead of continuing with a new token.
Enumeration establishes saved mappings only, not native absence or cleanup authority.
GET /pim-reconciliations
Inspect selected saved mappings against complete native inventory and current policy blockers.
Require policy:system-configure. Accept no body or conditional headers.
The request uses this repeated query parameter to select saved bindings:
| Parameter | Type | Requirement |
|---|
refKey | Repeated query string | Select 1–100 saved reference keys from enumeration. |
Policy deduplicates and sorts the selection.
Set REF_KEY to an exact saved reference key returned by binding enumeration.
curl --fail-with-body -i --get \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
--data-urlencode "refKey=${REF_KEY}" \
"${POLICY_API}/pim-reconciliations"
Return 200 and the registry ETag:
{
"target": "https://pim.example.test",
"ownershipVersion": 7,
"governedSetGeneration": 4,
"writerPending": false,
"bindings": [
{
"refKey": "dataelement:customer__EMAIL",
"persistedUid": "58",
"status": "missing",
"blockingPolicyIds": []
}
]
}
Each binding reports healthy or missing.
Retain the target, exact UID mappings, generation, and response header.
Stop cleanup when writerPending is true or any blocking policy remains.
Inspection does not reserve the registry. The decision rechecks these conditions.
Return 401 or 403 for identity or capability failures.
Return 404 for a missing registry or selected binding.
Return 409 for concurrent governed-set changes or reconciliation refusal.
Return 422 for invalid query selection.
Return 503 when complete native inventory is unavailable.
Restore that dependency before interpreting native presence.
POST /pim-reconciliations
Forget only selected, verified-stale saved mappings.
This command never deletes native resources.
Require policy:system-configure, registry If-Match, and Idempotency-Key.
Accept no query parameters.
The application/json body rejects extra fields:
| Field | Type | Requirement |
|---|
action | String | Supply forget_stale_bindings. |
target | String | Match the inspected configured PIM target exactly. |
bindings | Object | Map 1–100 selected nonblank reference keys to expected nonblank UID strings. |
reason | String | Supply 1–512 characters with nonblank trimmed text. |
governedSetGeneration | Integer | Match the inspected generation, at least one. |
Prepare forget-bindings.json with the inspected target, selected mappings, reason, and generation.
Use the example below only after verifying the same absence and blocker conditions.
curl --fail-with-body -i -X POST \
-H "@${POLICY_AUTH_HEADER:?Complete authentication setup}" \
-H "Content-Type: application/json" \
-H "If-Match: ${REGISTRY_ETAG}" \
-H "Idempotency-Key: ${DECISION_KEY}" \
--data-binary @forget-bindings.json \
"${POLICY_API}/pim-reconciliations"
Example forget-bindings.json, only after matching the preceding inspection:
{
"action": "forget_stale_bindings",
"target": "https://pim.example.test",
"bindings": {"dataelement:customer__EMAIL": "58"},
"reason": "Confirmed native absence and completed all contributing withdrawal work.",
"governedSetGeneration": 4
}
Return 200 and the resulting registry ETag:
{
"action": "forget_stale_bindings",
"status": "completed",
"reconciliationId": "forget-204",
"ownershipVersion": 8,
"forgottenBindings": {"dataelement:customer__EMAIL": "58"}
}
Return 401 or 403 for identity or capability failures.
Return 404 for a missing registry.
Return 409 for changed targets or generations, pending writers, live native resources,
changed mappings, active contributors, unfinished work, or conflicting decision-key reuse.
Return 503 when complete inventory is unavailable.
The shared 400, 412, 422, and 428 precondition rules also apply.
An identical accepted decision can replay without another registry transition.
Policy checks the configured target before replay.
Reenumerate after success and verify removal of exactly the selected mappings.
Do not interpret removal as native resource deletion or permission to recreate an identity.
Evidence and Stop Boundaries
Preserve policy and deployment identifiers, generation, safe error details, and timestamps.
For ownership decisions, also retain inspected mappings, target, registry header,
governed generation, affected revision identifiers, decision key, and reason.
Never include bearer tokens in this evidence.
Stop when inventory is incomplete, a candidate is incompatible, scope is unknown,
or a successor generation owns the work.
Send the response and identifiers to the Policy administrator. Ask the PIM administrator to investigate missing inventory or conflicting native objects.
Do not repair these conditions through database edits or spoofed identity headers.