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>
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
/demoorchestrator 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
/tokenizecorrectly.- 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/tokenize—terraform -chdir=terraform output -raw tokenize_urlRESTORE_URL=https://<...>/restore—terraform ... output -raw restore_urlAGENT_RUNTIME_ARN(the route's upstream) = printed byscripts/agentcore_setup.sh- Auth: public API Gateway HTTP API; send the shared secret in the
x-api-keyheader (Authorization: Bearer <secret>also works). The secret is the Terraformtokenize_api_keyvar (gitignoredterraform/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.
- AuthN / RBAC / business-purpose check (Fusion native).
- 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 withdeidentified_prompt; carrysession_idas policy/session context. - Forward to the AgentCore upstream with
{ "prompt": deidentified_prompt }— tokens only. - 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.
- 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). - 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.