workflow, memory, s3 and iam served requests without any Authorization header. Only sqs and the LLM models checked a token, so four upstreams were reachable from inside the cluster with no authentication at all. Set auth.required true on all five adapters. The dispatcher then enforces one capability per method, derived from the verb (internal/serviceadapter/router.go:142): GET/HEAD/OPTIONS -> "<service>:read" anything else -> "<service>:write" Those strings must exist as ZITADEL role keys with the colon. The project now holds memory:read, memory:write, workflow:read, workflow:execute, s3:read, s3:write, iam:read, iam:write, sqs:read and sqs:write, and the riotpiao user grant carries them, so a browser session keeps working. Correct the old comment: ZITADEL does store colon role keys. Verified by listing the project roles, which returned all eleven colon keys.