Bootstrapping Secrets
Bootstrap tokens authenticate edge agents during initial registration with Expanso Cloud. These tokens establish trust and should be provisioned securely before deploying the edge agent.
:::info Assumption This guide assumes you have already obtained a bootstrap token from Expanso Cloud. The examples focus on how to provision and mount the token securely, not on token generation. :::
Why Bootstrap Tokens Matter
- First Authentication: Bootstrap tokens are used only during initial agent startup
- Node Registration: Tokens authorize the edge agent to register with Expanso Cloud
- One-Time Use: After successful registration, agents use long-lived certificates for subsequent authentication
- High Value: Compromised tokens could allow unauthorized agents to join your fleet
Local File Storage (Linux)
Store bootstrap tokens as files with restrictive permissions.
Create Token File
# Create directory with root ownership
sudo mkdir -p /etc/expanso
# Write token with restricted permissions
echo "YOUR_BOOTSTRAP_TOKEN" | sudo tee /etc/expanso/bootstrap.token > /dev/null
sudo chmod 600 /etc/expanso/bootstrap.token
sudo chown root:root /etc/expanso/bootstrap.token
Permissions:
600ensures only owner (root) can read/write- No group or world access
Use Token File
# Read token from file during bootstrap
expanso-edge bootstrap --token "$(sudo cat /etc/expanso/bootstrap.token)"
# Then run the agent
expanso-edge run --config /etc/expanso/edge-config.yaml
Environment Variables (Systemd)
Use environment files for systemd-managed services.
Create Environment File
# Create environment file
echo "EXPANSO_EDGE_BOOTSTRAP_TOKEN=YOUR_BOOTSTRAP_TOKEN" \
| sudo tee /etc/expanso/bootstrap.env > /dev/null
# Restrict permissions
sudo chmod 600 /etc/expanso/bootstrap.env
sudo chown root:root /etc/expanso/bootstrap.env
Systemd Service Configuration
[Unit]
Description=Expanso Edge Node
After=network.target
[Service]
# Load environment variables from file
EnvironmentFile=-/etc/expanso/bootstrap.env
# Use environment variable in bootstrap command
ExecStart=/usr/local/bin/expanso-edge bootstrap \
--token ${EXPANSO_EDGE_BOOTSTRAP_TOKEN} \
run --config /etc/expanso/edge-config.yaml
Restart=unless-stopped
User=root
[Install]
WantedBy=multi-user.target
Enable and Start
sudo systemctl daemon-reload
sudo systemctl enable expanso-edge
sudo systemctl start expanso-edge
# Check status
sudo systemctl status expanso-edge
Docker Secrets
Docker Swarm secrets provide secure distribution to containers.
Create Docker Secret
# Create secret from file
echo "YOUR_BOOTSTRAP_TOKEN" > bootstrap.token
docker secret create expanso_bootstrap_token bootstrap.token
# Remove local file
rm bootstrap.token
Use in Docker Service
docker service create \
--name expanso-edge \
--secret expanso_bootstrap_token \
ghcr.io/expanso-io/expanso-edge:latest \
bootstrap --token /run/secrets/expanso_bootstrap_token run
Docker secret location: /run/secrets/expanso_bootstrap_token (mounted automatically)
Permissions: Docker manages permissions; only the container can read
Kubernetes Secrets
Use native Kubernetes Secrets for pod-based deployments.
Create Kubernetes Secret
# Create secret from literal value
kubectl create secret generic expanso-bootstrap-token \
--from-literal=bootstrap.token=YOUR_BOOTSTRAP_TOKEN \
--namespace=expanso-system
Or from a file:
echo "YOUR_BOOTSTRAP_TOKEN" > bootstrap.token
kubectl create secret generic expanso-bootstrap-token \
--from-file=bootstrap.token=bootstrap.token \
--namespace=expanso-system
rm bootstrap.token
Mount Secret in Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: expanso-edge
namespace: expanso-system
spec:
replicas: 1
selector:
matchLabels:
app: expanso-edge
template:
metadata:
labels:
app: expanso-edge
spec:
containers:
- name: expanso-edge
image: ghcr.io/expanso-io/expanso-edge:latest
args:
- bootstrap
- --token-file
- /etc/expanso/bootstrap.token
- run
volumeMounts:
- name: bootstrap-token
mountPath: /etc/expanso
readOnly: true
volumes:
- name: bootstrap-token
secret:
secretName: expanso-bootstrap-token
defaultMode: 0400 # Read-only for owner
Secret location in container: /etc/expanso/bootstrap.token
Best Practices
1. Restrict File Permissions
Always use chmod 600 for local token files:
sudo chmod 600 /etc/expanso/bootstrap.token
2. Rotate Bootstrap Tokens
- Generate new tokens periodically
- Revoke old tokens after rotation
- Use short-lived tokens when possible
3. Separate Bootstrap from Pipeline Secrets
- Don't reuse bootstrap tokens for pipeline authentication
- Use different storage mechanisms for different secret types
4. Audit Token Usage
- Monitor which nodes use which tokens
- Track token lifecycle in Expanso Cloud
- Alert on suspicious registration attempts
5. Secure Token Distribution
- Don't send tokens via email or chat
- Use secure channels (SSH, secure file transfer)
- Consider using configuration management tools (Ansible, Terraform)
Troubleshooting
Token Not Found
Symptom: Error: bootstrap token file not found
Solution: Verify file exists and has correct path:
ls -la /etc/expanso/bootstrap.token
Permission Denied
Symptom: Error: permission denied reading bootstrap token
Solution: Check file permissions and ownership:
sudo chmod 600 /etc/expanso/bootstrap.token
sudo chown root:root /etc/expanso/bootstrap.token
Invalid Token
Symptom: Error: invalid bootstrap token
Solution:
- Verify token hasn't expired in Expanso Cloud
- Check for extra whitespace in token file
- Regenerate token if necessary
Next Steps
- Configure pipelines? See Local Secrets for pipeline credential management
- Production deployment? Review External Secret Managers for enterprise patterns
- Need help? Check the Installation Guide for complete setup instructions