Skip to main content

Get Started with ICP Platform in 5 Minutes

Part 5 of the Zero-Trust Workload Identity Series

← Previous: Comparing Solutions


Overview

You understand the problem. You know how ICP Platform solves it. Now let's get you up and running in 5 minutes.

What you'll accomplish:

  1. Deploy ICP Agent to your infrastructure
  2. Register your first workload
  3. Issue your first SVID certificate
  4. Make an authenticated mTLS request

Prerequisites

  • Kubernetes cluster, Docker host, or Linux VM
  • Tenant ID from AuthSec (sign up at: support@authsec.ai)
  • Basic kubectl/docker/systemd knowledge

Step 1: Deploy ICP Agent

Choose your environment:

Option A: Kubernetes (DaemonSet)

# Add Helm repo
helm repo add authsec https://charts.authsec.ai
helm repo update

# Install ICP Agent
helm install icp-agent authsec/icp-agent \
--set agent.tenantId="your-tenant-id-here" \
--set agent.icpServiceUrl="https://dev.api.authsec.dev/spiresvc" \
--set agent.nodeId="k8s-node-01"

# Verify agent is running
kubectl get daemonset icp-agent
kubectl logs -l app=icp-agent

What this does:

  • Deploys agent as DaemonSet (1 pod per node)
  • Mounts Unix socket at /run/spire/sockets/agent.sock
  • Authenticates with ICP Server using tenant ID

Option B: Docker (Container)

# Create socket volume
docker volume create spire-agent-socket

# Run ICP Agent
docker run -d \
--name icp-agent \
--restart unless-stopped \
-v spire-agent-socket:/run/spire/sockets \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e ICP_AGENT_AGENT__TENANT_ID="your-tenant-id-here" \
-e ICP_AGENT_AGENT__ICP_SERVICE_URL="https://dev.api.authsec.dev/spiresvc" \
-e ICP_AGENT_AGENT__NODE_ID="docker-node-1" \
your-docker-registry.example.com/icp-agent:latest

# Verify agent is running
docker logs icp-agent

Time: 2 minutes

Option C: Linux VM (systemd)

# Download and install
curl -L https://releases.authsec.ai/icp-agent/latest/icp-agent-linux-amd64 \
-o /usr/local/bin/icp-agent
chmod +x /usr/local/bin/icp-agent

# Create config
cat > /etc/icp-agent/config.yaml <<EOF
agent:
tenant_id: "your-tenant-id-here"
icp_service_url: "https://dev.api.authsec.dev/spiresvc"
node_id: "vm-prod-01"
socket_path: "/run/spire/sockets/agent.sock"
EOF

# Create systemd service
cat > /etc/systemd/system/icp-agent.service <<EOF
[Unit]
Description=ICP Agent
After=network.target

[Service]
ExecStart=/usr/local/bin/icp-agent run
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# Start agent
systemctl daemon-reload
systemctl enable icp-agent
systemctl start icp-agent

# Verify
systemctl status icp-agent

Time: 3 minutes


Step 2: Register Your First Workload

Now register a workload so the agent knows which SPIFFE ID to issue. Login to app.authsec.dev to access the platform and register your workloads from there.

Kubernetes Workload

# Register frontend workload
curl -X POST https://dev.api.authsec.dev/spiresvc/api/v1/workloads \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spiffe_id": "spiffe://your-spiffe-id",
"parent_id": "spiffe://your-parent-id",
"selectors": {
"k8s:ns": "production",
"k8s:pod-label:app": "frontend"
}
}'

What this means:

  • Any pod in production namespace with label app=frontend will receive SPIFFE ID: spiffe://your-trust-domain.example.com/workload/frontend
  • Agent matches these selectors at runtime

Docker Workload

# Register payment service
curl -X POST https://dev.api.authsec.dev/spiresvc/api/v1/workloads \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spiffe_id": "spiffe://your-spiffe-id",
"parent_id": "spiffe://your-parent-id",
"selectors": {
"docker:label:app": "payment",
}
}'

Linux VM Workload

# Register database proxy
curl -X POST https://dev.api.authsec.dev/spiresvc/api/v1/workloads \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spiffe_id": "spiffe://your-spiffe-id",
"parent_id": "spiffe://your-parent-id",
"selectors": {
"unix:uid": "1000"
}
}'

Step 3: Integrate SDK in Your Application

Install the SDK and get your first SVID certificate.

Install SDK

pip install git+https://github.com/authsec-ai/sdk-authsec.git

Add to Your Application

Python (FastAPI example):

from fastapi import FastAPI
from authsec_sdk import QuickStartSVID
import httpx

app = FastAPI()

# Initialize SVID on startup
@app.on_event("startup")
async def startup():
global svid
svid = await QuickStartSVID.initialize()
print(f"Got SVID: {svid.spiffe_id}")

# Client-side: Make authenticated request
@app.get("/call-payment")
async def call_payment():
ssl_context = svid.create_ssl_context_for_client()

async with httpx.AsyncClient(verify=ssl_context) as client:
response = await client.post(
"https://payment-service.production.svc.cluster.local:8443/process",
json={"amount": 100}
)
return response.json()

# Server-side: Run with mTLS
if __name__ == "__main__":
import uvicorn
ssl_keyfile, ssl_certfile, ssl_ca_certs = svid.get_ssl_paths()

uvicorn.run(
app,
host="0.0.0.0",
port=8443,
ssl_keyfile=ssl_keyfile,
ssl_certfile=ssl_certfile,
ssl_ca_certs=ssl_ca_certs,
ssl_cert_reqs=2 # Require client cert
)

What this does:

  1. Connects to agent Unix socket
  2. Agent collects selectors (pod labels, etc.)
  3. Agent requests SVID from ICP Server
  4. SVID written to /tmp/spiffe-certs/
  5. SDK creates SSL context from certificates
  6. Automatic renewal every ~54 minutes (At 90% lifetime)

Step 4: Deploy Your Workload

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend # Matches selector!
spec:
nodeSelector:
kubernetes.io/hostname: "Your-node-name" # Matches selector!
containers:
- name: frontend
image: your-registry.example.com/frontend:latest
ports:
- containerPort: 8443
env:
- name: SPIFFE_ENDPOINT_SOCKET
value: unix:///run/spire/sockets/agent.sock

# Kubernetes Downward API for workload attestation
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: POD_LABEL_APP
valueFrom:
fieldRef:
fieldPath: metadata.labels['app']

volumeMounts:
- name: spire-agent-socket
mountPath: /run/spire/sockets
readOnly: true
volumes:
- name: spire-agent-socket
hostPath:
path: /run/spire/sockets
type: Directory

Docker Compose

version: '3.8'

services:
payment:
image: your-registry.example.com/payment:latest
labels:
app: "payment" # Matches selector!
env: "production" # Matches selector!
environment:
- SPIFFE_ENDPOINT_SOCKET=unix:///run/spire/sockets/agent.sock
volumes:
- spire-agent-socket:/run/spire/sockets:ro

volumes:
spire-agent-socket:
external: true

Step 5: Verify It's Working

Check Agent Logs

Kubernetes:

kubectl logs -l app=icp-agent --tail=50

Docker:

docker logs icp-agent --tail=50

Linux:

journalctl -u icp-agent -n 50

Look for:

✅ Agent authenticated with ICP Server
✅ Workload attestation successful
✅ Issued SVID: spiffe://your-trust-domain.example.com/workload/frontend
✅ SVID renewal scheduled

Check Application Logs

kubectl logs -l app=frontend --tail=20

Look for:

✅ Got SVID: spiffe://your-trust-domain.example.com/workload/frontend
✅ Certificate expires at: 2024-01-01 01:00:00
✅ mTLS connection established with payment service

Test mTLS Connection

# From frontend pod
curl -v https://payment-service:8443/health

# Should see:
# * TLSv1.3 (OUT), TLS handshake, Client hello
# * TLSv1.3 (IN), TLS handshake, Server hello
# * Server certificate: spiffe://your-trust-domain.example.com/workload/payment
# * Client certificate: spiffe://your-trust-domain.example.com/workload/frontend
# ✅ Connection established

Common Issues & Fixes

Issue: "Cannot connect to agent socket"

Fix:

# Check socket exists
ls -la /run/spire/sockets/agent.sock

# Check volume mount (Kubernetes)
kubectl describe pod <pod-name> | grep -A5 Volumes

# Check permissions
chmod 777 /run/spire/sockets # Socket directory

Issue: "No matching workload entry"

Fix:

# Check workload selectors match
# Agent collects: k8s:ns=production, k8s:pod-label:app=frontend
# Registered entry must be subset of collected selectors

# Verify pod labels
kubectl get pod <pod-name> -o jsonpath='{.metadata.labels}' | jq

# Check registered entry
curl https://your-icp-server.example.com/spiresvc/api/v1/workloads \
-H "Authorization: Bearer YOUR_API_TOKEN" | jq

Issue: "Certificate verification failed"

Fix:

# Ensure both client and server have trust bundle
ls -la /tmp/spiffe-certs/bundle.pem

# Check certificate is valid
openssl x509 -in /tmp/spiffe-certs/cert.pem -noout -text

# Verify SPIFFE ID in SAN
openssl x509 -in /tmp/spiffe-certs/cert.pem -noout -text | grep URI

What You've Accomplished

In 5 minutes, you:

✅ Deployed ICP Agent to your infrastructure ✅ Registered workloads with selectors ✅ Integrated SDK in your application ✅ Issued X.509 SVID certificates ✅ Established mTLS connections ✅ Enabled automatic certificate rotation

No API keys, no passwords, no manual certificate management!


Next Steps

Production Deployment

  • High Availability: Deploy agents to all nodes
  • Monitoring: Set up Prometheus metrics
  • Logging: Configure centralized logging
  • Security: Review security best practices

Advanced Features

  • Authorization Policies: Control which workloads can talk to each other
  • Multi-Cluster: Federate trust across Kubernetes clusters
  • Audit Logs: Track all SVID issuances and renewals
  • Custom Selectors: Add business-specific attestation logic

Deep Dive Guides


Get Help


Congratulations! You've secured your first workload with cryptographic identity.