WorkloadIdentity
WorkloadIdentity is the core resource in Riptides. It defines a cryptographic identity for a workload, determining its SPIFFE ID, how the workload is matched on a host, what TLS policy applies, and which other identities it is allowed to communicate with.
- API Group:
core.riptides.io - Version:
v1alpha1 - Kind:
WorkloadIdentity - Plural:
workloadidentitys
workloadID
Section titled “workloadID”| Type | string |
| Required | Yes |
A hierarchical identifier for this workload. Combined with the trust domain, it forms the workload’s SPIFFE ID:
spiffe://<trustDomain>/<workloadID>For example, a workloadID of myapp/backend/api in the trust domain example.com produces the SPIFFE ID spiffe://example.com/myapp/backend/api.
| Type | object |
| Required | Yes |
Determines which daemon or daemon group this identity is scoped to. Exactly one of the following must be set:
daemon.id(string) — Scope to a single daemon by its ID.daemonGroup.id(string) — Scope to a daemon group by its ID. All daemons in the group will serve this identity.
selectors
Section titled “selectors”| Type | array of selector objects |
| Required | Yes |
Selectors define the criteria a daemon uses to match a running process to this identity. Each selector object contains key-value pairs that must all match for the workload to be identified. Multiple selector objects in the array are evaluated with OR logic (any match is sufficient). A key within an object can also list multiple values; the process matches if it has any one of them.
Commonly used selector keys:
| Key | Description |
|---|---|
process:name | Name of the running process binary. |
process:cmdline | Full command line of the process. |
k8s:pod:name | Kubernetes pod name. |
k8s:pod:namespace | Kubernetes pod namespace. |
k8s:pod:serviceaccount | Kubernetes pod’s service account name. |
k8s:container:name | Kubernetes container name within the pod. |
k8s:label:<label-name> | Kubernetes pod label value. |
k8s:annotation:<key> | Kubernetes pod annotation value. |
docker:name | Docker container name. |
docker:label:<key> | Docker container label value. |
ec2:instance:id | AWS EC2 instance ID. |
ec2:placement:region | AWS region. |
gcp:instance:id | GCP Compute Engine instance ID. |
gcp:project:id | GCP project ID. |
azure:subscription:id | Azure subscription ID. |
linuxos:name | Linux distribution name. |
See Workload Attestation for the complete metadata label list produced by every collector, and for host-scoped vs. process-scoped selector behavior.
| Type | object |
| Required | No |
Configures the SVID (SPIFFE Verifiable Identity Document) issued to this workload.
x509— X.509 SVID settings.dnsNames(arrayofstring) — Additional DNS SANs to include in the certificate.ttl(string, pattern^\d+s$) — Time-to-live for the X.509 certificate (e.g.,3600s).
jwt— JWT SVID settings.ttl(string, pattern^\d+s$) — Time-to-live for JWT SVIDs (e.g.,300s).
connection
Section titled “connection”| Type | object |
| Required | No |
Default connection policy for this workload’s inbound traffic.
protocol(string) — Application protocol hint. Set toHTTP1to enable in-kernel HTTP/1 request inspection, which is required for HTTP-level features such as credential injection and the ingresshttpRequestPathallowlist. Defaults to unset (no HTTP inspection).tls.mode(string) — TLS mode. When unset, inbound traffic defaults toPERMISSIVE(so existing plaintext callers keep working during enrollment); outbound (egress) connections are always upgraded to mutual TLS regardless of mode, since Riptides initiates them. Valid options:SIMPLE— Server-side TLS only (workload presents its certificate; client is not verified).MUTUAL— Mutual TLS (both sides present and verify certificates).PERMISSIVE— Accept both plaintext and mTLS connections. Useful during migration.
tls.intercept(boolean, nullable) — Whentrue, the Riptides kernel module transparently intercepts connections to upgrade them to TLS.tls.skipVerification(boolean, nullable) — Whentrue, skip peer certificate verification (not recommended for production).
allowedSPIFFEIDs
Section titled “allowedSPIFFEIDs”| Type | object |
| Required | No |
Defines the default set of SPIFFE IDs this workload is authorized to communicate with.
inbound(arrayofstring) — SPIFFE IDs allowed to connect to this workload.outbound(arrayofstring) — SPIFFE IDs this workload is allowed to connect to.
ingress
Section titled “ingress”| Type | array of ingress rule objects |
| Required | No |
Per-port inbound connection policies. Each entry overrides the default connection and allowedSPIFFEIDs for a specific listening port.
port(integer, required) — The listening port number.connection(object) — Connection settings for this port (same schema as top-levelconnection).allowedSPIFFEIDs(arrayofstring) — SPIFFE IDs permitted on this port.svid(object) — Per-port SVID overrides (same schema as top-levelsvid).workloadID(string) — Optional workload ID override for this ingress port.httpRequestPath(arrayofstring) — Restricts which HTTP request paths an unauthenticated client (one presenting no valid SPIFFE/mTLS identity — for example a plaintext caller on aPERMISSIVEport) may reach on this port. Only the listed paths are forwarded to the application; any other request — or anything that is not a recognizable HTTP/1 request — is reset, the same outcome aMUTUALport gives an unauthenticated caller. Clients that present a valid mTLS identity are not restricted and reach every path. An empty or omitted list imposes no restriction — thePERMISSIVEport then behaves as usual; useMUTUALif you want identity required on every path. Requires the connectionprotocolto beHTTP1(set on the ingress or inherited from the top-levelconnection); otherwise the resource is rejected at admission. Each entry must be a unique, absolute path with no query string or fragment (also enforced at admission). Matching is exact and ignores the query string —/healthzmatches/healthzand/healthz?t=1, but not/healthz/or/healthz/live. The common use is exposing health and readiness probes without mTLS while keeping every other path identity-gated.
egress
Section titled “egress”| Type | array of egress rule objects |
| Required | No |
Egress rules define how this workload connects to downstream services. Each rule targets one or more services (matched by label selectors) and can override the default connection policy, allowed SPIFFE IDs, SVID settings, and workload ID on a per-service basis.
selectors(arrayof selector objects, required) — Label selectors that match against Service labels to identify the target services.connection(object) — TLS/connection settings for outbound connections to matched services.allowedSPIFFEIDs(arrayofstring) — SPIFFE IDs of the expected remote peers.svid(object) — Per-egress SVID overrides.workloadID(string) — Optional workload ID override for this egress rule.
Status
Section titled “Status”WorkloadIdentity resources do not expose a status subresource. The daemon resolves the identity assignment based on scope and selectors and reports operational state through other system resources.
Examples
Section titled “Examples”Basic workload identity with mTLS
Section titled “Basic workload identity with mTLS”A simple workload identity for a backend service, scoped to a daemon group, with permissive TLS and inbound/outbound access control:
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: cartservice namespace: riptides-systemspec: workloadID: myapp/app/cartservice scope: daemonGroup: id: daemongroup/prod-us-east-1/workers selectors: - k8s:label:app: cartservice k8s:pod:namespace: myapp process:name: cartservice connection: tls: mode: PERMISSIVE allowedSPIFFEIDs: inbound: - spiffe://example.com/myapp/app/frontend - spiffe://example.com/myapp/app/checkoutservice outbound: - spiffe://example.com/myapp/app/redis-cartWorkload with TLS intercept for credential injection
Section titled “Workload with TLS intercept for credential injection”A workload that connects to external APIs with transparent TLS interception. Credential injection is configured in the associated CredentialBinding resources.
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: support-assistant namespace: riptides-systemspec: workloadID: support-assistant/app/assistant-api scope: daemonGroup: id: daemongroup/prod-us-east-1/workers selectors: - k8s:label:app: support-assistant k8s:pod:namespace: support-assistant process:name: node connection: tls: mode: PERMISSIVE intercept: trueWorkload with per-port ingress rules
Section titled “Workload with per-port ingress rules”A workload that exposes multiple ports with different TLS policies per port:
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: control-center namespace: riptides-systemspec: workloadID: platform/control-center scope: daemonGroup: id: daemongroup/prod-us-east-1/infra selectors: - k8s:container:name: control-center k8s:label:app.kubernetes.io/component: control-center process:name: java connection: tls: mode: PERMISSIVE ingress: - port: 9021 connection: tls: mode: PERMISSIVE - port: 8080 connection: tls: mode: MUTUAL allowedSPIFFEIDs: - spiffe://example.com/platform/control-center egress: - allowedSPIFFEIDs: - spiffe://example.com/platform/kafka-broker connection: tls: mode: PERMISSIVE selectors: - app: kafka-cluster-encrypted-listeners - connection: tls: mode: SIMPLE selectors: - app: external-analytics allowedSPIFFEIDs: inbound: - spiffe://example.com/platform/control-center/health-checkAllowing unauthenticated health probes on specific paths
Section titled “Allowing unauthenticated health probes on specific paths”A workload that requires mTLS in general but lets unauthenticated health probes
reach /healthz and /readyz over plaintext. Port 8080 runs PERMISSIVE (so the
identity-less probe is accepted) with protocol: HTTP1, and httpRequestPath
limits unauthenticated callers to the probe endpoints — every other path on the
port still requires a verified identity:
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: api-server namespace: riptides-systemspec: workloadID: myapp/app/api-server scope: daemonGroup: id: daemongroup/prod-us-east-1/workers selectors: - k8s:label:app: api-server k8s:pod:namespace: myapp connection: tls: mode: MUTUAL # omit to default to PERMISSIVE (inbound); egress is always strict ingress: - port: 8080 connection: protocol: HTTP1 tls: mode: PERMISSIVE # accept plaintext probes on this port httpRequestPath: - /healthz - /readyz allowedSPIFFEIDs: - spiffe://example.com/myapp/app/frontendRelated Resources
Section titled “Related Resources”- CredentialBinding — Bind credentials to this workload for injection using
CredentialBinding.propagation.injectionselectors. - CredentialSource — Define where credentials come from.
- Service — Define the services that egress selectors match against.
- API Reference Overview