Skip to content

Verify a delegation token

Verify the X-Omnia-Delegation header on a tool call with pkg/delegation, so your handler knows which user and which agent the call was made for.

  • A tool backend registered as a handler in a ToolRegistry, with delegation.enabled: true on that handler. See Opting in.
  • A route from your backend to the operator’s JWKS endpoint. Inside the cluster that is the operator Service; outside it, enable operator.delegationAPI.publicJWKS in the chart. See Verifying it for the URLs.
  • The handler’s audience, <namespace>/<registry>/<handler>. For the handler http in registry orders in namespace acme, that is acme/orders/http.
  1. Create one verifier when your service starts. It fetches the operator’s public keys on first use, caches them, and refetches only when a token names a key id it does not hold.

    import (
    "github.com/go-logr/logr"
    "github.com/altairalabs/omnia/pkg/delegation"
    )
    // jwksURL and the audience are illustrative; use your own.
    var v = delegation.NewVerifier(jwksURL, "acme/orders/http", logr.Discard())

    The second argument is the audience from the prerequisites. The verifier rejects any token minted for a different one.

  2. In the handler, verify the header before you trust anything in the request.

    func handler(w http.ResponseWriter, r *http.Request) {
    claims, err := v.Verify(r.Context(), r.Header.Get(delegation.HeaderName))
    if err != nil {
    // No token, or one that cannot be judged. Refuse, or carry on
    // unattributed; the choice is yours.
    http.Error(w, "forbidden", http.StatusForbidden)
    return
    }
    agent := claims.Act.Sub // the agent, as the operator found it
    user := claims.Subject // always present; check the origin first
    if claims.UserIsVerified() {
    // origin is "oidc": the operator checked an identity provider itself.
    }
    }
  3. Decide what to do with an unverified user. Act on claims.Subject for anything that spends a person’s credentials only when claims.UserIsVerified() is true. The other origins are listed in What is in the token.

Call the tool through an agent whose handler has delegation.enabled: true. Log claims.Subject and claims.Act.Sub in the handler and confirm both are set for that call.

Then call your endpoint directly, without the header. Verify returns an error, so the request takes your err != nil branch. A handler without delegation.enabled behaves the same way, because the runtime sends no header.

The audience you passed to NewVerifier differs from the handler’s <namespace>/<registry>/<handler>. Your service cannot derive it, so check the three names against the ToolRegistry.

Verify fails with an unknown key id or a JWKS fetch error

Section titled “Verify fails with an unknown key id or a JWKS fetch error”

jwksURL is wrong or unreachable from your backend. Fetch it with curl from the same place the backend runs. After a key rotation, the verifier refetches on the next unrecognised key id, but no more often than every five seconds.

The tool call fails before it reaches your handler

Section titled “The tool call fails before it reaches your handler”

The runtime could not obtain a token from the operator, and it fails the call rather than sending it without one. Check the agent’s runtime logs.