Getting Started with Riptides
This guide walks you through connecting your first daemon and assigning a workload identity. Choose the installation method that matches your infrastructure:
- Virtual Machines / Bare Metal — install the daemon via a single script on any Linux host
- Kubernetes — deploy the daemon as a Helm chart into an existing cluster
Both methods share the same control plane and use JoinToken authentication to register daemons.
Prerequisites
Section titled “Prerequisites”Before you begin, make sure you have:
kubectlinstalled and configured to communicate with the Riptides-hosted control plane (provided after signup)- The
oidc-loginkubectl plugin (also distributed askubelogin) installed on your machine — this is required because the Riptides control plane authenticates human users via OIDC. Without it,kubectlcommands will fail with an authentication error.
Install the oidc-login Plugin
Section titled “Install the oidc-login Plugin”If you already use krew, install the plugin with:
kubectl krew install oidc-loginIf kubectl krew is not available, install krew first using the official instructions:
Then install and verify:
kubectl krew install oidc-loginkubectl oidc-login --versionIf you prefer a package manager, the same plugin is also distributed as kubelogin.
Network Requirements
Section titled “Network Requirements”The daemon must reach the control plane on the following ports. Open these in your firewall, security group, or egress policy before proceeding:
| Port | Protocol | Purpose |
|---|---|---|
| 8443 | HTTPS | Primary API — kubectl commands and daemon registration |
| 9443 | gRPC/TLS | Daemon attestation and certificate signing |
| 8001 | TCP | Persistent tunnel for daemons behind NAT or strict firewalls |
Tip: Port 8001 is most important for VMs and bare-metal nodes behind NAT. Kubernetes daemons typically only need 8443 and 9443.
Step 1: Connect to the Hosted Control Plane
Section titled “Step 1: Connect to the Hosted Control Plane”The Riptides control plane is hosted and operated by Riptides. Log in to the control plane web UI at the URL provided in your access details email.
Configure kubectl to use the Riptides API server with the kubeconfig downloaded from the UI:
export KUBECONFIG=~/.riptides/kubeconfigWhen you run your first kubectl command, the oidc-login plugin will open a browser window for authentication. After authenticating, the token is cached and subsequent commands will not require re-authentication until the token expires.
Verify connectivity:
riptides-cli ctl get namespacesNote: See the Control Plane page for more details on the hosted control plane architecture.
Step 2: Create a JoinToken Verifier
Section titled “Step 2: Create a JoinToken Verifier”A Verifier tells the control plane which authentication methods it should accept from daemons. Start with the joinToken verifier for a simple token-based flow. This step applies to both Kubernetes and VM/bare metal daemons:
apiVersion: auth.riptides.io/v1alpha1kind: Verifiermetadata: name: jointoken namespace: riptides-systemspec: joinToken: {}Apply it:
riptides-cli ctl apply -f verifier-jointoken.yamlConfirm the Verifier is available:
riptides-cli ctl get verifiersExpected output:
NAME STATEjointoken AvailableStep 3: Create a JoinToken
Section titled “Step 3: Create a JoinToken”Create a JoinToken resource that the daemon will present during registration. Set token to a strong, unique value and give the token a workloadID and an expiration time:
apiVersion: auth.riptides.io/v1alpha1kind: JoinTokenmetadata: name: my-first-daemon-token namespace: riptides-systemspec: token: "my-secure-join-token" workloadID: "riptides/daemon/my-first-node" expireAt: "2026-12-31T23:59:59Z"Apply it:
riptides-cli ctl apply -f jointoken.yamlTip: Rotate join tokens regularly and set short expiration windows in production environments.
Virtual Machines / Bare Metal
Section titled “Virtual Machines / Bare Metal”The installer detects your distribution and kernel version, downloads the right packages, writes the daemon configuration, and starts the systemd service.
Step 1: Run the Installer
Section titled “Step 1: Run the Installer”curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.io \ --join-token "<your-join-token>"EC2 / AWSIID
Section titled “EC2 / AWSIID”On EC2, the script auto-detects the instance and authenticates using the AWS Instance Identity Document — no join token required:
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.ioPass --awsiid explicitly if auto-detection does not trigger (e.g. when IMDSv2 is restricted).
Azure VMs
Section titled “Azure VMs”On Azure, the script auto-detects the instance and authenticates using the Azure Instance Metadata Service — no join token required. The VM must have a managed identity attached:
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.ioPass --azureimds explicitly if auto-detection does not trigger. See Connect Azure VMs for the required Verifier setup.
Supported Platforms
Section titled “Supported Platforms”| Distribution | Package |
|---|---|
| Ubuntu, Debian | .deb |
| RHEL, CentOS, Rocky Linux, AlmaLinux | .rpm |
| Amazon Linux 2023 | .rpm |
| Fedora | .rpm |
Packages are built for amd64 and arm64. The installer picks the right one automatically.
Options
Section titled “Options”| Flag | Default | Description |
|---|---|---|
--controlplane-url URL | — | Control plane URL (required) |
--join-token TOKEN | — | Join token for daemon authentication |
--awsiid | auto-detected on EC2 | Use AWS Instance Identity Document auth |
--azureimds | auto-detected on Azure | Use Azure Instance Metadata Service auth |
--version VERSION | latest | Daemon version to install (e.g. v0.5.12) |
--driver-version VERSION | latest | Driver version to install (e.g. v0.5.15) |
--data-dir DIR | /var/lib/riptides | Directory for daemon state and certificates |
Pinning versions
Section titled “Pinning versions”curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \ --controlplane-url https://<your-env-id>.console.riptides.io \ --join-token "<your-join-token>" \ --version v0.5.12 \ --driver-version v0.5.15The daemon and driver are versioned independently. Omit either flag to use the latest release of that component.
What the script does
Section titled “What the script does”- If Riptides is already installed and the driver is present, starts the daemon service if it is not running and prints a status summary. No reinstallation is performed.
- Detects your distribution (Debian/Ubuntu →
.deb, RHEL/Amazon Linux/Fedora →.rpm), architecture, and running kernel version. - Downloads and installs the kernel driver loader from riptides-packages/driver-loader. The loader downloads the pre-built driver package for your kernel and loads it via the
riptides-modulessystemd unit. If no pre-built package exists for your kernel, the loader queues a remote build and the script streams its output while waiting — this can take up to 30 minutes. - Downloads and installs the daemon package from riptides-packages/daemon.
- Writes
/etc/riptides/config.yaml(mode0600, owned byroot) with the control plane URL, trust domain, and auth plugin configuration. - Enables and starts the
riptidessystemd service. The daemon authenticates to the control plane on first start using the configured join token, AWSIID, or AzureIMDS.
Step 2: Verify the Daemon Connected
Section titled “Step 2: Verify the Daemon Connected”Once the daemon is running, confirm it has registered with the control plane:
riptides-cli ctl get daemonsYou should see your VM daemon listed with its workload ID:
NAME WORKLOAD IDe2140516-678a-419d-9a4c-156e971583ae riptides/daemon/my-first-nodeThe WORKLOAD ID will match the workloadID specified in the JoinToken.
Kubernetes
Section titled “Kubernetes”Follow this section to install the Riptides daemon as a Helm chart on an existing Kubernetes cluster.
Additional prerequisites for Kubernetes:
- Kubernetes cluster v1.26 or later
- Helm v3.12 or later
Step 1: Deploy the Daemon
Section titled “Step 1: Deploy the Daemon”Install the Riptides daemon using Helm. The daemon connects back to the control plane using the join token you created.
helm install daemon oci://ghcr.io/riptides-packages/helm/daemon \ --namespace riptides-system \ --create-namespace \ --set config.daemon.controlPlane.enabled=true \ --set config.daemon.controlPlane.url=https://<your-env-id>.console.riptides.io \ --set config.daemon.controlPlane.authPlugin.type=joinToken \ --set config.daemon.controlPlane.authPlugin.config.token=my-secure-join-tokenAlternatively, create a values.yaml file for the daemon:
config: daemon: controlPlane: enabled: true url: https://<your-env-id>.console.riptides.io authPlugin: type: joinToken config: token: my-secure-join-token dataDir: /data/riptidesThen install with:
helm install daemon oci://ghcr.io/riptides-packages/helm/daemon \ --namespace riptides-system \ --create-namespace \ -f daemon-values.yamlStep 2: Verify the Daemon Connected
Section titled “Step 2: Verify the Daemon Connected”Once the daemon pod is running, check that it has registered with the control plane:
riptides-cli ctl get daemonsYou should see your daemon listed with its workload ID:
NAME WORKLOAD IDe2140516-678a-419d-9a4c-156e971583ae riptides/daemon/my-first-nodeThe WORKLOAD ID will match the workloadID specified in the JoinToken. If the daemon does not appear, check the daemon pod logs for connection errors.
Assigning Identities to Workloads
Section titled “Assigning Identities to Workloads”Step 1: Create Your First WorkloadIdentity
Section titled “Step 1: Create Your First WorkloadIdentity”A WorkloadIdentity assigns a SPIFFE identity to processes that match a set of selectors. The following example assigns an identity to an Nginx process running in a specific Kubernetes namespace. The same resource type is used regardless of whether the daemon is running on Kubernetes or a VM.
apiVersion: core.riptides.io/v1alpha1kind: WorkloadIdentitymetadata: name: nginx-web namespace: riptides-systemspec: workloadID: my-app/web/nginx selectors: - process:name: nginx k8s:pod:namespace: my-app k8s:label:app: nginx connection: tls: mode: PERMISSIVEApply it:
riptides-cli ctl apply -f workload-identity.yamlThis WorkloadIdentity will issue the SPIFFE ID spiffe://example.com/my-app/web/nginx to any process named nginx in a pod labeled app: nginx within the my-app namespace.
Selector Reference
Selectors identify which processes receive the identity. Common selector keys include:
| Selector | Description |
|---|---|
process:name | Name of the running process binary |
k8s:pod:namespace | Kubernetes namespace the pod runs in |
k8s:label:<key> | Value of a Kubernetes pod label |
k8s:container:name | Name of the Kubernetes container |
For the full list of available selectors, see the WorkloadIdentity reference.
TLS Modes
The connection.tls.mode field controls how TLS is enforced for the workload:
| Mode | Description |
|---|---|
SIMPLE | One-way TLS — the workload presents its certificate to clients |
MUTUAL | Mutual TLS — both sides present and verify certificates |
PERMISSIVE | Accepts both plaintext and mTLS connections (useful during migration) |
Step 2: Verify the Identity Was Assigned
Section titled “Step 2: Verify the Identity Was Assigned”After applying the WorkloadIdentity, verify that the control plane has matched it against running workloads:
riptides-cli ctl get workloadidentitiesYou should see the nginx-web identity listed. If the daemon is running on a node where an Nginx process matches the selectors, the identity will be assigned and a SPIFFE ID issued.
Troubleshooting
Section titled “Troubleshooting”Authentication failed
Section titled “Authentication failed”The daemon logs will show the reason. Common causes:
- Join token expired or not applied — confirm
riptides-cli ctl get jointokensshows the token and thatexpireAthas not passed. Generate a new one and update/etc/riptides/config.yaml(VM) or your Helm values (Kubernetes), then restart the daemon:Terminal window sudo systemctl restart riptides - Wrong control plane URL — verify it matches exactly what was provided after signup.
- Outbound connectivity blocked — the daemon needs access to the control plane on ports
8443and9443:Terminal window curl -v https://<your-env-id>.console.riptides.io:8443/healthz
Service fails to start (VM / bare metal)
Section titled “Service fails to start (VM / bare metal)”sudo systemctl status riptidessudo journalctl -u riptides -n 50 --no-pagerCommon causes:
- YAML syntax error in
/etc/riptides/config.yaml:Terminal window python3 -c "import yaml; yaml.safe_load(open('/etc/riptides/config.yaml'))" - Kernel module not loaded — check
lsmod | grep riptidesandsudo systemctl status riptides-modules. - Port blocked — the daemon needs outbound access to the control plane on ports
8443and9443.
Daemon pod in CrashLoopBackOff (Kubernetes)
Section titled “Daemon pod in CrashLoopBackOff (Kubernetes)”Check the pod logs for the root cause:
kubectl logs -n riptides-system -l app.kubernetes.io/name=daemon --previousCommon causes:
- Image pull failure — the
regcredpull secret may be missing or the GHCR token has expired. Re-create it and restart the pod. - Wrong control plane URL — double-check the URL matches exactly what was provided after signup.
Daemon does not appear in riptides-cli ctl get daemons
Section titled “Daemon does not appear in riptides-cli ctl get daemons”The pod may be running but failing to register with the control plane. Check live logs:
kubectl logs -n riptides-system -l app.kubernetes.io/name=daemon -fCommon causes:
- JoinToken expired or not applied — confirm
riptides-cli ctl get jointokensshows the token and thatexpireAthas not passed. - Port 8443 or 9443 blocked — verify the daemon node can reach the control plane on both ports.
oidc-login does not open a browser
Section titled “oidc-login does not open a browser”The OIDC login flow requires a desktop browser. On headless servers, the plugin will print a URL to open manually. If your environment blocks outbound OAuth redirects, check the console.riptides.io dashboard for alternative authentication options.
Next Steps
Section titled “Next Steps”- Connect AWS Nodes — use the AWSIID verifier for automatic, token-free daemon authentication on AWS
- Connect GCP Instances — use the GCPIIT verifier for automatic daemon authentication on GCP
- mTLS Between Services — enforce mutual TLS between your first two workloads
- WorkloadIdentity Reference — full API specification for WorkloadIdentity resources
- Verifier Reference — all supported verifier types and their configuration