Save, Review, Approve, and Inspect Delivery
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:reviewandpolicy:approvethrough approved mappings. - Give the auditor
policy:auditfor 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.jsonThe 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.jsonThe server derives protection methods from the selected inputs. An empty
actionslist does not mean null-read permission. Optional trusted applications belong incompileRequest.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.jsonExpect
201, a policy identifier, and aDraft-ETagheader. Save creates a draft. It does not approve or publish it. Save can retain validation findings that prevent later submission. KeepPOLICY_IDfor policy paths. Do not replace it withdraftPolicyIdor a snapshot identifier. ThedraftPolicyIdidentifies the stable Draft Policy. The draft summary’scycleNumberidentifies 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.jsonExpect
200with the draft enteringin_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.jsonReview 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 inDraft-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.jsonExpect
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 sendapprovedBy. 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_APIandPOLICY_IDto 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.jsonExpect
200with 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.jsonThe governed view selects approved inputs, not an open replacement draft’s scope. The default
view=latestselects 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.
- ←Previous: Policy API Operation Directory
- Next: Application Programming Interface Errors and Safe Recovery→
Feedback
Was this page helpful?