Files
hncb-fusion-deid-demo/fusion/POLICY_SETUP.md
Conan Scott 2443e0e6f3 docs: reframe POLICY_SETUP as a Fusion de-id policy
Position /tokenize + /restore as the transform backend of an inline request/
response policy on the route to the AgentCore agent, with Fusion as the
non-bypassable enforcement + audit point — rather than a manual HTTP
orchestrator. Adds an honest Fusion-vs-/demo governance note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 18:26:18 +10:00

4.9 KiB

Fusion (shared SaaS) policy setup — de-identification as a gateway policy

Fusion (Axway Amplify AI Gateway) is a shared SaaS instance, configured in the console — not deployed by this repo. Here it is the enforcement plane in front of the AgentCore agent: de-identification is a policy on the route, not application code. /tokenize and /restore are the policy's transform backend (they hold the detector + vault on-prem); Fusion applies them inline to traffic.

Why put Fusion in the path at all? Functionally, everything below is an HTTP call — the /demo orchestrator proves a plain client can do the same mechanics. That is the point: the mechanics are not the differentiator. Fusion adds what a plain call cannot:

  • Non-bypassable enforcement — de-id is applied at the gateway to all AI traffic, not trusted to each app to call /tokenize correctly.
  • Central audit — the gateway's own trace is the compliance artifact proving only tokens ever reached the model. (See the money-shot check in the README.)
  • Reuse — one policy governs every model/agent/app behind Fusion; routing, rate-limits, and guardrails come with it.

Drop Fusion and you lose enforcement and audit, not capability.

The policy model

Fusion fronts the AgentCore Runtime as a governed route. Two policies wrap it:

advisor ─▶ [ Fusion route to the agent ]
             │  request policy  (ingress) ── tokenize transform ─▶ /tokenize
             ▼
           AgentCore Runtime  (sees TOKENS only)
             │  response policy (egress)  ── restore transform ──▶ /restore
             ▼
advisor ◀────┘

The transforms run inside the policy boundary; the raw name never crosses it.

Backend the policy calls

  • TOKENIZE_URL = https://<api-id>.execute-api.<region>.amazonaws.com/tokenizeterraform -chdir=terraform output -raw tokenize_url
  • RESTORE_URL = https://<...>/restoreterraform ... output -raw restore_url
  • AGENT_RUNTIME_ARN (the route's upstream) = printed by scripts/agentcore_setup.sh
  • Auth: public API Gateway HTTP API; send the shared secret in the x-api-key header (Authorization: Bearer <secret> also works). The secret is the Terraform tokenize_api_key var (gitignored terraform/local.auto.tfvars, never committed) — hand it to the console operator out of band.
    • Note: a Lambda Function URL was the first choice, but this account's SCP blocks unauthenticated Function URLs, so the public front door is API Gateway.

Request policy — ingress (prompt bound for the agent)

Applied to every request on the route; the app cannot skip it.

  1. AuthN / RBAC / business-purpose check (Fusion native).
  2. Tokenize transform: POST { query }TOKENIZE_URL{ deidentified_prompt, session_id }. The endpoint runs detect → mint → vault-write → splice (typed findings, never a redacted blob). Replace the outbound prompt with deidentified_prompt; carry session_id as policy/session context.
  3. Forward to the AgentCore upstream with { "prompt": deidentified_prompt } — tokens only.
  4. Audit: record the tokenized payload; the raw query never leaves the policy.

Response policy — egress (agent's answer)

Applied to every response on the route.

  1. Restore transform: POST { session_id, text }RESTORE_URL{ final } (vault lookup scoped to this session; re-attaches identity at the envelope and swaps any inline tokens).
  2. Return { "final": ..., "deidentified_prompt": ... } so the UI renders the restored-vs-tokenized split view.

Vault item shape (DynamoDB, written by the tokenize transform)

One row per detected entity. value is the original PII (so restore can put it back); a resolvable PERSON also gets a customer_id so the RAG tool can turn the token into a de-identified evidence package.

{ "token": "CUST_863651", "type": "PERSON",    "value": "王小明",
  "session_id": "<session>", "expires_at": <epoch+ttl>, "customer_id": "cust-0001" }
{ "token": "TW_683250",   "type": "TW_ROC_ID", "value": "A123456789",
  "session_id": "<session>", "expires_at": <epoch+ttl> }

(The seed's --with-demo-token writes a different type=CUSTOMER, value=cust-0001 row; that's only a standalone RAG test aid, not what the tokenize transform mints.)

Fusion vs. the /demo orchestrator (be honest on camera)

gateway_api/orchestrator/ (/demo) runs the identical tokenize → agent → restore mechanics over plain HTTP, so the Fusion-less demo works end to end. Show that to prove the data-flow. Then make the governance point: only Fusion turns those mechanics into a mandatory, audited policy across all AI traffic — the enforcement boundary an app-level HTTP call can't guarantee.

Not automated here: Fusion is shared SaaS and configured by a human in the console. This file is the spec for that configuration.