Scrydon
Security

SPIFFE / mTLS

Service-to-service authentication in Scrydon — Dapr-native SPIFFE identity, mTLS, and the four-layer trust chain.

All internal service-to-service communication in Scrydon is mutually authenticated via SPIFFE identity over mTLS. There are no shared bearer tokens for service callers, and there is no fallback path that bypasses identity verification.

The four-layer trust chain

Each internal call passes through four independent checks. Any failure denies the request.

LayerWhat it checks
TransportDapr mTLS between sidecars. Certificates issued by the Dapr Sentry CA.
NetworkDapr access-control list (defaultAction: deny). Only explicitly allowed app IDs reach a given route.
ApplicationThe receiving service validates the caller's app ID, namespace, and required capability.
ProvenanceThe receiver verifies the request traversed the Dapr sidecar by inspecting a sidecar-issued token.

Fail-closed: if any layer fails, the request is denied with no fallback.

Identity verification

Every internal route resolves the caller through a single helper:

  1. Extract the caller identity — app ID, namespace, sidecar token.
  2. Look up the required capability for the route.
  3. Match the identity against the route's allowlist.
  4. Match the capability against the caller's grant set.
  5. Return decision — authorised, or denied with a structured error.

The decision is recorded in the audit log as an AUTH_INTERNAL_* event.

Capabilities

Internal calls don't get a blank cheque. Each receiver declares which capabilities it accepts, and each caller is granted only the capabilities it needs. Examples:

CapabilityGranted toPurpose
llm:completeThe LLM gatewayPermission to invoke an LLM model
managed-table:readThe analytics service, the ontology serviceRead managed-table rows
managed-table:agent-createThe workflow runtimeCreate agent-managed tables
kb:readThe retrieval surface, the chat surfaceRead knowledge-base documents at the caller's clearance
secrets:internalThe workflow runtimeFetch decrypted credentials for the active execution grant

Capabilities are checked per request. There is no notion of "this caller is admin so anything goes."

Dev mode

Local development without a Dapr control plane runs in a degraded mode: a short-lived dev identity marker substitutes for SPIFFE identity. This mode is rejected outright in production. The receiver inspects the deployment mode and refuses to honour a dev marker if it's not running in a dev environment.

What this gives you

  • Spoofing protection. A request claiming to come from an internal service must actually traverse a Dapr sidecar with a valid mTLS certificate. Hand-crafted requests with forged headers are rejected at the transport layer.
  • Lateral-movement containment. A compromised pod can only call services its app ID is explicitly allowed to reach. There is no "internal trust zone" that grants everyone access to everything.
  • Audit clarity. Every internal call is identified by the caller's app ID, not by an opaque service-account token. The audit log can answer "which service called this endpoint" deterministically.

The Dapr control plane runs in your cluster. Scrydon does not have access to your service mesh identity material — the Sentry CA is yours, and its private key never leaves your cluster.

  • Network boundary — the wider perimeter around the mesh.
  • Ingress hardening — how external requests are scrubbed before they reach the mesh.
  • Authorization — how user-driven authorisation interacts with service-to-service identity.
On this page

On this page