Skip to content

PATTERN Cited by 1 source

Machine-to-machine authorization

Shape

Reuse the same fine-grained-authorization architecture built for end-user API calls to authorize service-to-service calls, with one substitution: the identity comes from OAuth client-credentials rather than user login.

Service A → Cognito m2m user pool (client-credentials grant)
          → Access token w/ service claims
            {service_id, tier, allowed_ops, rate_limit}
          → API call to Service B (through API Gateway)
          → API Gateway → Lambda authorizer
          → Validate token, extract service claims
          → AVP.IsAuthorized(service_policy_store, principal=Service A,
                             action=requested_op, resource=..., context=...)
          → Cached decision → Forward to Service B

(Source: sources/2026-02-05-aws-convera-verified-permissions-fine-grained-authorization)

Why it works

  • Same architecture as user-facing authz. The authorizer doesn't care whether the JWT represents a user or a service — it reads claims, evaluates policies, returns Allow/Deny. Convera's operational insight: "this architectural reuse meant Convera didn't need to rebuild their authorization infrastructure."
  • Per-service policy stores give each service its own fine-grained policies (what actions it can perform on what resources) without bloating a shared policy store.
  • Service identity in the token. Token claims include:
  • service_id — who's calling.
  • tier — service classification (e.g., internal vs external partner).
  • allowed_ops — pre-computed action allowlist (policy engine can still re-verify).
  • rate_limit — per-service throttling context.
  • Cache reuse. Service-to-service traffic has higher repeat rate than user traffic (same service calling the same endpoint repeatedly); the decision cache absorbs most calls.

Why build this at all

Alternatives that don't work well for fine-grained service authz:

  • mTLS + "any service on the mesh can call any other". Insufficient — doesn't express "service A can call POST /transfers but not DELETE /users." mTLS proves identity, not authorization.
  • API keys + IP allowlists. Brittle; coupled to deployment; no per-action granularity.
  • IAM service-role authorization on AWS. Works for AWS-service authz (IAM); doesn't directly express application-level operation authorization (ViewTransferButton vs InitiateTransfer).

Convera's architecture uses Cognito m2m + AVP to get:

  • Identity + authentication: Cognito m2m user pool.
  • Fine-grained authorization: AVP + Cedar policies.
  • One coherent policy expression for both users and services.

Trade-offs

  • Token-refresh cost on services. Client-credentials flows require the client service to re-authenticate when tokens expire; short token lifetimes increase load on Cognito.
  • Service identity sprawl. Every client service needs a Cognito app client registration + a policy-store entry. Requires an onboarding process.
  • Not a replacement for network segmentation. m2m authz proves "this service may call this action" — it doesn't prevent a leaked m2m credential from reaching your API at all. Pair with network policy (PrivateLink, VPC security groups) for defense in depth.

Context propagation for zero-trust

If the calling service is itself serving a user request, two approaches:

  • Delegated authorization. Propagate the user's JWT to the downstream service; backend evaluates the user's policies. Each tier re-verifies (patterns/zero-trust-re-verification).
  • Service-on-behalf-of. Caller service gets an m2m token + passes user identity as context; backend policies express "service + on-behalf-of user" rules.

Convera's source describes m2m but not the explicit pattern for on-behalf-of; typical shape is to include the original user's sub claim in the downstream call context.

Seen in

  • sources/2026-02-05-aws-convera-verified-permissions-fine-grained-authorization — canonical instantiation: Convera's service-to-service layer reuses the same API-Gateway + Lambda-authorizer + AVP shape built for customer APIs; services authenticate via Cognito m2m user pool (client credentials), tokens carry service-id / tier / allowed-ops / rate-limits; per-service policy store in AVP; decision cached at API Gateway.
Last updated · 200 distilled / 1,178 read