Attestation and Selectors
Attestation is the process of verifying identity before granting trust. Riptides performs attestation at two levels: node attestation (proving the daemon’s identity to the control plane) and workload attestation (proving a process’s identity to the kernel module). Both must succeed before a workload receives an identity.
Node Attestation
Section titled “Node Attestation”Node attestation establishes trust between an daemon and the control plane. When an daemon starts, it must prove its identity using a Verifier configured on the control plane. Only after successful node attestation does the daemon receive policies and certificates.
Verifier Types
Section titled “Verifier Types”Each Verifier type uses a different proof mechanism appropriate to the node’s environment:
| Verifier | Environment | Proof |
|---|---|---|
| JoinToken | Any | A pre-shared token created on the control plane. Suitable for bootstrapping and development. |
| AWSIID | AWS | The AWS Instance Identity Document, a signed document that proves the daemon runs on a specific EC2 instance. |
| GCPIIT | GCP | A GCP Instance Identity Token, a signed JWT that proves the daemon runs on a specific Compute Engine instance. |
| K8sSAT | Kubernetes | A Kubernetes Service Account Token projected into the daemon pod. The control plane validates it against the cluster’s signing keys. |
| X509CertPOP | Any with PKI | Proof of possession of an X.509 certificate issued by a trusted CA. |
| SSHCertPOP | Any with SSH CA | Proof of possession of an SSH certificate issued by a trusted CA. |
| JWT | Any | A JWT token from a trusted issuer. |
Verifiers are defined as CRDs on the control plane. Multiple verifiers can coexist, allowing daemons in different environments to attest using the mechanism native to their platform.
Example: JoinToken Verifier
Section titled “Example: JoinToken Verifier”apiVersion: auth.riptides.io/v1alpha1kind: Verifiermetadata: name: dev-jointoken namespace: riptides-systemspec: joinToken: {}---apiVersion: auth.riptides.io/v1alpha1kind: JoinTokenmetadata: name: daemon-token-001 namespace: riptides-systemspec: token: "<token-value>"The daemon configuration references the token:
daemon: controlPlane: url: https://controlplane.example.com:8443 authPlugin: type: JoinToken config: token: "<token-value>"Example: AWS Instance Identity Document
Section titled “Example: AWS Instance Identity Document”apiVersion: auth.riptides.io/v1alpha1kind: Verifiermetadata: name: aws-verifier namespace: riptides-systemspec: AWSIID: {} requiredMetadata: - awsiid:account:id: "<aws-account-id>" - awsiid:region: "us-east-1"This verifier accepts daemons running on EC2 instances in the specified account and region. The daemon automatically retrieves the instance identity document from the EC2 metadata service and presents it during attestation.
Workload Attestation
Section titled “Workload Attestation”Workload attestation happens at connection time. When a process opens a new network connection, the daemon evaluates the connecting process against selectors defined in WorkloadIdentity resources using collected metadata. Only processes that satisfy all selectors for an identity are allowed to use that identity.
This evaluation is not a one-time check. Every new connection triggers selector evaluation, so a process that previously matched but has since changed (for example, a different binary was exec’d into the same PID) will not pass attestation.
Selectors
Section titled “Selectors”Selectors are typed key-value pairs that describe workload attributes. A WorkloadIdentity specifies one or more selectors; a process must match all of them to receive the identity.
Process Selectors
Section titled “Process Selectors”Match based on process-level attributes observed by the kernel:
| Selector | Description | Example Value |
|---|---|---|
process:name | The process executable name | nginx |
process:cmdline | The full command line | node dist/server.js |
Kubernetes Selectors
Section titled “Kubernetes Selectors”Match based on Kubernetes metadata collected by the daemon:
| Selector | Description | Example Value |
|---|---|---|
k8s:label:<key> | A label on the pod | k8s:label:app = frontend |
k8s:pod:namespace | The pod’s namespace | production |
k8s:container:name | The container name within the pod | api |
OS Selectors
Section titled “OS Selectors”Match based on the host operating system:
| Selector | Description | Example Value |
|---|---|---|
linuxos:name | The Linux distribution name | ubuntu |
Metadata Collection
Section titled “Metadata Collection”The daemon enriches process data with environmental metadata that powers selector matching. The metadata collected depends on the environment:
- Kubernetes — Pod name, namespace, labels, annotations, container names, service account. Collected via the Kubernetes API.
- AWS — Instance ID, account ID, region, availability zone, instance type. Collected from the EC2 Instance Metadata Service (IMDS).
- GCP — Instance ID, project, zone. Collected from the GCP metadata server.
- OS — Distribution name, kernel version, hostname. Collected from the local system.
- Network — Interface names, IP addresses. Collected from the local system.
This metadata is used by the daemon during selector evaluation to incorporate both process-level and environment-level attributes when matching a process to a WorkloadIdentity.