OIDC Authentication
YipYap implements Knative Eventing’s OIDC authentication model in both directions, outbound deliveries attach an OIDC bearer token; the ingest endpoint verifies incoming tokens against a configured issuer. Combined with Knative’s EventPolicy CRD, this gives you fine-grained, cryptographically-verified access control over who can send events where.
Authentication modes
Section titled “Authentication modes”YipYap supports three authentication postures:
- None (default), no OIDC. Anyone with the sink URL or integration key can post.
- External IdP, YipYap signs outbound tokens via a third-party IdP (Keycloak, Dex, Authentik, Okta, Auth0, Google, Azure AD) using client-credentials. Inbound verification targets that same IdP.
- Self-hosted JWKS (SaaS only), YipYap is the IdP for outbound deliveries. Each org gets a stable
sub = https://console.yipyap.run/orgs/{org_id}. Consumers trust YipYap’s/.well-known/jwks.jsondirectly, no external IdP needed. Not available in FOSS; self-hosters bring their own IdP.
Outbound: attaching a bearer token
Section titled “Outbound: attaching a bearer token”On a cloudevent_http notification channel, set the auth config to oidc and fill in the token URL + client credentials. YipYap fetches a token via client-credentials grant and attaches Authorization: Bearer <jwt> to every outbound POST.
Example channel config (API form):
{ "sink_url": "https://broker-ingress.knative-eventing.svc.cluster.local/my-ns/default", "mode": "binary", "auth": { "type": "oidc", "oidc": { "issuer": "https://dex.example.com", "token_url": "https://dex.example.com/token", "client_id": "yipyap-delivery", "client_secret": "super-secret", "audience": "https://broker-ingress.knative-eventing.svc.cluster.local/my-ns/default" } }}Tokens are cached per (issuer, audience, client_id) with a 30-second refresh-ahead window. Multiple YipYap replicas share the cache (process-local today; JetStream KV-backed in a future phase).
Inbound: verifying bearer tokens at ingest
Section titled “Inbound: verifying bearer tokens at ingest”Configure per-org verification by storing JSON under the org setting key cloudevents.ingest.auth:
{ "type": "oidc", "oidc": { "issuer": "https://kubernetes.default.svc", "jwks_url": "", "audiences": [ "https://console.yipyap.run/orgs/your-org-id/ingest" ] }}With this set, every ingest request must carry Authorization: Bearer <jwt>. YipYap validates it against the issuer’s JWKS (cached, respects Cache-Control) and records the verified sub claim on the resulting check row for audit.
Error-code mapping:
| Verifier result | HTTP status |
|---|---|
| Valid token | 200 OK |
| Missing bearer | 401 Unauthorized |
| Expired / bad signature / malformed | 401 Unauthorized |
| Wrong issuer / wrong audience | 403 Forbidden |
| JWKS endpoint unreachable | 503 Service Unavailable (retryable) |
SaaS self-hosted JWKS
Section titled “SaaS self-hosted JWKS”On SaaS, YipYap publishes its own JWK Set at https://console.yipyap.run/.well-known/jwks.json. Each org has a stable sub; consumers configure YipYap as a trusted issuer in their Knative cluster.
Key rotation, weekly rotation with a 14-day overlap window. Old keys remain in JWKS for 14 days after they’re retired so tokens minted during the overlap keep validating. After 14 days, retired keys drop out of JWKS and any outstanding tokens signed with them fail verification.
Signing algorithms, YipYap’s JWK Set advertises public keys under one of these algs (default EdDSA / Ed25519):
EdDSA(Ed25519), default. Smallest keys, fastest sign/verify.RS256,RS384,RS512, RSA PKCS#1 v1.5 with SHA-256/384/512.PS256,PS384,PS512, RSA-PSS. Preferred modern RSA.ES256,ES384,ES512, ECDSA on P-256/P-384/P-521.
Symmetric algorithms (HS*) and alg: none are explicitly excluded, they have no place in a public JWKS.
EventPolicy recipes
Section titled “EventPolicy recipes”Knative’s EventPolicy CRD authorises specific identities to deliver events to a Broker, Channel, Sequence, or Parallel. Combine it with YipYap’s outbound OIDC to create fine-grained, per-org access control.
Recipe 1, allow only YipYap’s service account
Section titled “Recipe 1, allow only YipYap’s service account”Shared external IdP (Okta/Auth0/Google). YipYap’s client-credentials flow produces a token with sub = client:yipyap-delivery.
apiVersion: eventing.knative.dev/v1alpha1kind: EventPolicymetadata: name: allow-yipyap-delivery namespace: my-nsspec: to: - ref: apiVersion: eventing.knative.dev/v1 kind: Broker name: default from: - sub: "client:yipyap-delivery"Only events with a verified sub = client:yipyap-delivery are accepted by the Broker; others are rejected with 403.
Recipe 2, allow a specific yipyap org (SaaS-only)
Section titled “Recipe 2, allow a specific yipyap org (SaaS-only)”YipYap’s self-hosted JWKS produces tokens with sub = https://console.yipyap.run/orgs/{org_id}. Trust it in your cluster and write a per-org policy:
apiVersion: eventing.knative.dev/v1alpha1kind: EventPolicymetadata: name: allow-yipyap-org-acme namespace: my-nsspec: to: - ref: apiVersion: eventing.knative.dev/v1 kind: Broker name: default from: - sub: "https://console.yipyap.run/orgs/01HY1..."If you run multiple YipYap orgs against the same cluster (e.g. distinct environments), one policy per org gives you precise isolation.
Recipe 3, filter by event type as well
Section titled “Recipe 3, filter by event type as well”Stack policies: separate policies for alert.* vs monitor.* vs maintenance.* let different teams own different subsets.
apiVersion: eventing.knative.dev/v1alpha1kind: EventPolicymetadata: name: allow-yipyap-alerts-only namespace: my-nsspec: to: - ref: apiVersion: eventing.knative.dev/v1 kind: Broker name: alerts-broker from: - sub: "https://console.yipyap.run/orgs/01HY1..." filters: - cesql: "type LIKE 'run.yipyap.alert.%'"The alerts-broker accepts only yipyap alert events from the named org. Monitor and maintenance events flow elsewhere.
FOSS notes
Section titled “FOSS notes”- Self-hosted JWKS is not available in FOSS. Bring your own IdP.
- Dex, Keycloak, and Authentik are the tested options. Any compliant OIDC provider works.
- YipYap’s outbound channel config accepts any IdP’s token URL, no vendor coupling.
Reply events: how authentication and validation interact
Section titled “Reply events: how authentication and validation interact”Three annotation-only reply types let your sinks add context to an alert’s timeline by returning a CloudEvent in the HTTP response body:
run.yipyap.reply.alert.claimed.v1: a “claimed by” entry on the timeline.run.yipyap.reply.alert.enriched.v1: attach structured context (links, log previews).run.yipyap.reply.alert.linked.v1: attach an external reference (Jira, PagerDuty, etc.).
A reply must:
- Be a CloudEvent in the HTTP response body (structured
application/cloudevents+jsonOR binary-modece-*headers plus body). - Carry
ce_alertrefequal to the outbound event’sid. The dispatcher rejects replies whosece_alertrefdoesn’t match a recent outbound event in its in-process LRU (24-hour retention window). - Be opted in on the channel. Each
cloudevent_httpchannel has anAccepted Repliesconfiguration; only reply types you have checked will be acted on. Others are silently dropped (logged and counted in metrics, no timeline row). - Not exceed the rate cap. Per (org, reply-type) cap defaults to 60/minute; configurable per channel.
The sub claim from OIDC verification is recorded on every timeline row for audit. State-mutating reply types (suppress, escalate, route, deregister, and the rest) require OIDC to be enabled on the channel; annotation-only replies are accepted either way.
What’s next
Section titled “What’s next”- Event catalog, full wire reference.
- Send heartbeats, now with OIDC.
- Receive alerts, updated for OIDC delivery.