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.
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