DEV Community

Cover image for Introducing Omega: SPIFFE Workload Identity + AuthZEN Authorization in a Single Binary
kt
kt

Posted on

Introducing Omega: SPIFFE Workload Identity + AuthZEN Authorization in a Single Binary

Standing up workload identity in a real cluster usually means running
four projects: SPIRE for SVID issuance, OPA or Cedar for authorization,
an OIDC provider for federation, and a separate audit pipeline.

The standards finally caught up. OpenID AuthZEN Authorization API 1.0
was approved as a Final Specification on 2026-01-12.
Cedar joined CNCF Sandbox on 2025-10-08
and is in production at Cloudflare, MongoDB, StrongDM, and AWS Bedrock
AgentCore. SPIFFE is the de-facto workload identity model.

Omega is my attempt at wiring those
pieces into one Apache-2.0 binary.

A few terms first

If any of these are unfamiliar, the rest of the article assumes them.

Term One-line definition
SPIFFE A spec for workload identity. Defines spiffe://trust-domain/path IDs.
SVID SPIFFE Verifiable Identity Document. Either an X.509 cert or a JWT.
Workload API A local gRPC endpoint a workload calls to fetch its current SVID.
PDP / PEP Policy Decision Point answers "allow?". Policy Enforcement Point asks the question.
AuthZEN An OpenID spec for the HTTP+JSON wire format between a PEP and a PDP.
Cedar A small, analyzable policy language from AWS, now CNCF Sandbox.

What Omega is

One binary with three subcommands:

  • omega server runs the control plane: a CA that issues SPIFFE X.509-SVIDs and JWT-SVIDs, an AuthZEN 1.0 PDP backed by Cedar, an audit log, and SPIFFE federation.
  • omega agent runs the SPIFFE Workload API on a Unix domain socket and attests workloads by their UID via peercred.
  • omega <CRUD> is the CLI for domains, policies, and SVIDs.

What ships today

Repo: https://github.com/0-draft/omega. Items marked tracked are
GitHub issues, not features in the source tree.

Layer Status
SPIFFE X.509-SVID implemented
SPIFFE JWT-SVID (JWKS) implemented
AuthZEN 1.0 PDP (Cedar) implemented
SPIFFE federation implemented
Tamper-evident audit implemented
Postgres backend (HA) implemented
Kubernetes operator implemented
cert-manager Issuer implemented
Observability implemented
Admin UI implemented
AI agent delegation example
OIDC IdP federation hub tracked
CSI driver tracked
PQC (ML-DSA / ML-KEM) tracked

60-second hands-on

git clone https://github.com/0-draft/omega
cd omega
make docker-up
Enter fullscreen mode Exit fullscreen mode

That brings up the control plane on :8080, two node agents (giving
the same UID two distinct SPIFFE IDs over separate sockets), the
hello-svid server and client (which mTLS-handshakes and prints the
verified peer SPIFFE ID), and the admin dashboard on :3000.

Hit the AuthZEN endpoint:

curl -sS -X POST http://127.0.0.1:8080/access/v1/evaluation \
  -H 'Content-Type: application/json' \
  -d '{"subject":{"type":"Spiffe","id":"spiffe://omega.local/example/web"},
       "action":{"name":"GET"},
       "resource":{"type":"HttpPath","id":"/api/foo"}}'
# {"decision":false}
Enter fullscreen mode Exit fullscreen mode

Drop a Cedar policy in policies/ and pass --policy-dir policies to
the server:

permit (
  principal == Spiffe::"spiffe://omega.local/example/web",
  action    == Action::"GET",
  resource  == HttpPath::"/api/foo"
);
Enter fullscreen mode Exit fullscreen mode

Re-run the curl and the response flips to
{"decision":true,"reasons":["policy0"]}. Tear it down with make
docker-down
.

How the audit log stays tamper-evident

Every write goes through one append path that computes a row hash from
the previous row's hash plus this row's content
(internal/server/storage/audit.go):

// hash = sha256(seq | ts_nano | kind | actor | subject | decision | payload | prev_hash)
h := sha256.New()
fmt.Fprintf(h, "%d|%d|%s|%s|%s|%s|", ev.Seq, ev.Ts.UnixNano(),
    ev.Kind, ev.Actor, ev.Subject, ev.Decision)
h.Write([]byte(ev.Payload))
h.Write([]byte("|"))
h.Write([]byte(ev.PrevHash))
Enter fullscreen mode Exit fullscreen mode

AppendAudit is serialized through a single mutex so the
prev_hash lookup and the INSERT cannot interleave. A Verify walk
re-computes every row and reports the first mismatched seq, so any
deletion or in-place edit shows up the next time you scan.

AI agent delegation example

The examples/mcp-a2a-delegation/ directory shows how a human, a
coordinator agent, and a sub-agent chain through Omega. Each hop calls
POST /v1/token/exchange, which mints a new JWT-SVID whose act claim
is the previous token's subject. After two hops the leaf token looks
like:

{
  "sub": "spiffe://omega.local/agents/claude-code/github-tool",
  "act": {
    "sub": "spiffe://omega.local/agents/claude-code",
    "act": {
      "sub": "spiffe://omega.local/humans/alice"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The tool-server verifies the leaf with the omega JWKS, checks the
audience, and walks the act chain. With
--enforce-token-exchange-policy the Cedar policy gets the final say
on whether each exchange is allowed, and every decision lands in the
audit log.

This is a reference example today, not an in-tree library.

What comes next

Three things have to land before the project moves off v0.0.x:

  1. OmegaIdentity CRD plus operator-to-control-plane mTLS.
  2. SPIFFE federation bundle authenticity (peer mTLS plus first-time pin) and JWKS federation.
  3. An OIDC IdP federation adapter, AWS first.

PQC (ML-DSA / ML-KEM) and a CSI driver are deliberately later. CRL and
OCSP are not on the list at all; short-lived SVIDs plus rotation is
the revocation story. Detailed non-goals (secrets storage, end-user
login UI, service-mesh data plane, SIEM, agent runtime) live in
docs/non-goals.md.

Try it

If you have spent an evening stitching SPIRE to OPA to Keycloak to
Loki, please clone it, run make docker-up, and tell me where it
breaks.

Top comments (0)