Remote Cache Authentication¶
Secure your remote cache with token-based authentication.
Overview¶
rninja uses token-based authentication for remote cache access:
- Server maintains a list of valid tokens
- Clients present a token with each request
- Invalid tokens are rejected
Server Configuration¶
Setting Tokens¶
Command Line¶
rninja-cached \
--listen tcp://0.0.0.0:9999 \
--storage /var/lib/rninja-cache \
--tokens "token1,token2,token3"
Environment Variable¶
Generating Secure Tokens¶
# Generate random token
openssl rand -hex 32
# Or using /dev/urandom
head -c 32 /dev/urandom | base64
# Example output:
# a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef12345678
Token Best Practices¶
- Use long, random tokens (at least 32 characters)
- Unique tokens per use case (team, CI, read-only)
- Rotate tokens periodically
- Never share tokens in plain text
Client Configuration¶
Setting the Token¶
Secure Token Storage¶
Environment File (Development)¶
Protect the file:
Credential Manager (Recommended)¶
# Store in system keyring
secret-tool store --label="rninja cache token" service rninja key cache_token
# Retrieve
export RNINJA_CACHE_TOKEN=$(secret-tool lookup service rninja key cache_token)
CI Secrets¶
Use your CI platform's secret management:
# GitHub Actions
env:
RNINJA_CACHE_TOKEN: ${{ secrets.CACHE_TOKEN }}
# GitLab CI
variables:
RNINJA_CACHE_TOKEN: $CACHE_TOKEN # From CI variables
Token Strategies¶
Single Token (Simple)¶
One token for everyone:
Pros: Simple Cons: Can't revoke individual access
Per-Team Tokens¶
Different tokens per team:
# Server
--tokens "team-a-token,team-b-token,ci-token"
# Team A clients
export RNINJA_CACHE_TOKEN=team-a-token
# Team B clients
export RNINJA_CACHE_TOKEN=team-b-token
# CI systems
export RNINJA_CACHE_TOKEN=ci-token
Pros: Can revoke per-team Cons: More tokens to manage
Read/Write Separation¶
Different tokens for different access levels:
# Server
--tokens "write-token,read-token"
# CI (read/write)
export RNINJA_CACHE_TOKEN=write-token
export RNINJA_CACHE_PUSH_POLICY=always
# Developers (read-only)
export RNINJA_CACHE_TOKEN=read-token
export RNINJA_CACHE_PUSH_POLICY=never
Access Control
Currently, all valid tokens have the same permissions. Use push/pull policies on clients for access control.
Token Rotation¶
Rotation Process¶
-
Add new token to server:
-
Update clients to use new token:
-
Remove old token after all clients updated:
Automated Rotation Script¶
#!/bin/bash
# rotate_token.sh
# Generate new token
NEW_TOKEN=$(openssl rand -hex 32)
# Update server config
sed -i "s/RNINJA_SERVER_TOKENS=.*/RNINJA_SERVER_TOKENS=old-token,$NEW_TOKEN/" /etc/rninja/env
# Restart server
systemctl restart rninja-cached
echo "New token: $NEW_TOKEN"
echo "Update clients, then remove old-token from server config"
Security Hardening¶
Network Security¶
Combine authentication with network controls:
TLS Encryption¶
Use a reverse proxy for TLS:
server {
listen 443 ssl;
server_name cache.example.com;
ssl_certificate /etc/ssl/certs/cache.crt;
ssl_certificate_key /etc/ssl/private/cache.key;
location / {
proxy_pass http://127.0.0.1:9999;
}
}
Clients use HTTPS endpoint (via proxy):
Audit Logging¶
Monitor authentication attempts:
Troubleshooting¶
Authentication Failed¶
# Verify token is set
echo $RNINJA_CACHE_TOKEN | wc -c # Check length
# Verify token matches server
# On server: check RNINJA_SERVER_TOKENS
# On client: check RNINJA_CACHE_TOKEN
Token Not Being Sent¶
Server Rejecting Valid Token¶
# Check for whitespace in token
echo "'$RNINJA_CACHE_TOKEN'" | cat -A
# Regenerate token without special characters
openssl rand -hex 32
Example Configurations¶
Small Team¶
Enterprise¶
# Server
RNINJA_SERVER_TOKENS=eng-token,qa-token,ci-token,readonly-token
# Engineering
RNINJA_CACHE_TOKEN=eng-token
# QA
RNINJA_CACHE_TOKEN=qa-token
# CI/CD
RNINJA_CACHE_TOKEN=ci-token
RNINJA_CACHE_PUSH_POLICY=always
# External contractors (read-only)
RNINJA_CACHE_TOKEN=readonly-token
RNINJA_CACHE_PUSH_POLICY=never