Skip to content

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
Typestring
RequiredYes

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.

Typeobject
RequiredYes

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.
Typearray of selector objects
RequiredYes

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:

KeyDescription
process:nameName of the running process binary.
process:cmdlineFull command line of the process.
k8s:pod:nameKubernetes pod name.
k8s:pod:namespaceKubernetes pod namespace.
k8s:pod:serviceaccountKubernetes pod’s service account name.
k8s:container:nameKubernetes container name within the pod.
k8s:label:<label-name>Kubernetes pod label value.
k8s:annotation:<key>Kubernetes pod annotation value.
docker:nameDocker container name.
docker:label:<key>Docker container label value.
ec2:instance:idAWS EC2 instance ID.
ec2:placement:regionAWS region.
gcp:instance:idGCP Compute Engine instance ID.
gcp:project:idGCP project ID.
azure:subscription:idAzure subscription ID.
linuxos:nameLinux distribution name.

See Workload Attestation for the complete metadata label list produced by every collector, and for host-scoped vs. process-scoped selector behavior.

Typeobject
RequiredNo

Configures the SVID (SPIFFE Verifiable Identity Document) issued to this workload.

  • x509 — X.509 SVID settings.
    • dnsNames (array of string) — 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).
Typeobject
RequiredNo

Default connection policy for this workload’s inbound traffic.

  • protocol (string) — Application protocol hint. Set to HTTP1 to enable in-kernel HTTP/1 request inspection, which is required for HTTP-level features such as credential injection and the ingress httpRequestPath allowlist. Defaults to unset (no HTTP inspection).
  • tls.mode (string) — TLS mode. When unset, inbound traffic defaults to PERMISSIVE (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) — When true, the Riptides kernel module transparently intercepts connections to upgrade them to TLS.
  • tls.skipVerification (boolean, nullable) — When true, skip peer certificate verification (not recommended for production).
Typeobject
RequiredNo

Defines the default set of SPIFFE IDs this workload is authorized to communicate with.

  • inbound (array of string) — SPIFFE IDs allowed to connect to this workload.
  • outbound (array of string) — SPIFFE IDs this workload is allowed to connect to.
Typearray of ingress rule objects
RequiredNo

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-level connection).
  • allowedSPIFFEIDs (array of string) — SPIFFE IDs permitted on this port.
  • svid (object) — Per-port SVID overrides (same schema as top-level svid).
  • workloadID (string) — Optional workload ID override for this ingress port.
  • httpRequestPath (array of string) — Restricts which HTTP request paths an unauthenticated client (one presenting no valid SPIFFE/mTLS identity — for example a plaintext caller on a PERMISSIVE port) 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 a MUTUAL port 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 — the PERMISSIVE port then behaves as usual; use MUTUAL if you want identity required on every path. Requires the connection protocol to be HTTP1 (set on the ingress or inherited from the top-level connection); 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 — /healthz matches /healthz and /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.
Typearray of egress rule objects
RequiredNo

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 (array of 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 (array of string) — SPIFFE IDs of the expected remote peers.
  • svid (object) — Per-egress SVID overrides.
  • workloadID (string) — Optional workload ID override for this egress rule.

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.

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/v1alpha1
kind: WorkloadIdentity
metadata:
name: cartservice
namespace: riptides-system
spec:
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-cart

Workload 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/v1alpha1
kind: WorkloadIdentity
metadata:
name: support-assistant
namespace: riptides-system
spec:
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: true

A workload that exposes multiple ports with different TLS policies per port:

apiVersion: core.riptides.io/v1alpha1
kind: WorkloadIdentity
metadata:
name: control-center
namespace: riptides-system
spec:
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-check

Allowing 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/v1alpha1
kind: WorkloadIdentity
metadata:
name: api-server
namespace: riptides-system
spec:
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/frontend