# Fusion (shared SaaS) policy setup (steps 2, 3-route, 8) Fusion is a **shared SaaS instance** — configured in the Amplify AI Gateway console, not deployed by this repo. Because it's SaaS it **cannot reach private VPC resources or use local AWS creds**, so it does not call Presidio or DynamoDB directly. Instead it calls two **public HTTPS endpoints** this repo exposes (built in `gateway_api/`, tasks T1/T2), which do the detection, minting, vault writes, and restore on the AWS side. Fusion owns the orchestration and routing. ## Endpoints Fusion calls - `TOKENIZE_URL` = `https://.execute-api..amazonaws.com/tokenize` (ingress: detect + mint + vault-write + splice). Get the live value with `terraform -chdir=terraform output -raw tokenize_url`. - `RESTORE_URL` = `https://<...>/restore` (egress: vault lookup + re-attach identity — T2) - `AGENT_RUNTIME_ARN` (or its HTTPS invoke endpoint) = printed by `scripts/agentcore_setup.sh` - **Auth (T1, live):** the endpoint is a public API Gateway HTTP API; it requires a shared secret in the **`x-api-key`** header (a `Authorization: Bearer ` header also works). Configure Fusion's outbound request to send it. The secret is the Terraform `tokenize_api_key` var (kept in gitignored `terraform/local.auto.tfvars`, never committed) — hand it to the Fusion 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 instead. ## Ingress policy (advisor request → cloud) 1. **Authenticate** the advisor; apply the RBAC / business-purpose check. 2. **Tokenize**: POST `{ query }` to `TOKENIZE_URL`. Receive `{ deidentified_prompt, session_id }`. (The endpoint runs detect → mint → vault-write → splice; detection returns typed findings, never a redacted blob.) 3. **Route**: invoke the agent with `{ "prompt": deidentified_prompt }`. 4. **Trace**: log the **tokenized** payload only — never the raw query. ## Egress policy (cloud response → advisor) 1. Receive the agent's de-identified result. 2. **Restore**: POST `{ session_id, text }` to `RESTORE_URL`; receive `{ final }`. 3. Return `{ "final": ..., "deidentified_prompt": ... }` so the UI shows the split view. ## Vault item shape (DynamoDB, written by /tokenize) 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": "", "expires_at": , "customer_id": "cust-0001" } { "token": "TW_683250", "type": "TW_ROC_ID", "value": "A123456789", "session_id": "", "expires_at": } ``` (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 `/tokenize` mints.) ## Why this split Keeping detection, minting, and the vault behind `/tokenize` and `/restore` means the only things exposed to the SaaS gateway are two authenticated HTTPS endpoints — no AWS creds or private resources leave the account, and Fusion stays a pure orchestration/routing layer. That is also the cleanest story on camera: the gateway owns the flow; the cloud only ever sees tokens.