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:
- Deploy ICP Agent to your infrastructure
- Register your first workload
- Issue your first SVID certificate
- 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
productionnamespace with labelapp=frontendwill 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:
- Connects to agent Unix socket
- Agent collects selectors (pod labels, etc.)
- Agent requests SVID from ICP Server
- SVID written to
/tmp/spiffe-certs/ - SDK creates SSL context from certificates
- 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
- Kubernetes Integration Guide - Production K8s deployment
- Docker Integration Guide - Docker Swarm and multi-host
- Linux VM Integration Guide - systemd, Ansible, monitoring
Get Help
- Questions? support@authsec.dev
- Documentation: Integration Guides
- Issues? Check troubleshooting sections in integration guides
Congratulations! You've secured your first workload with cryptographic identity.