Authentication¶
Complete guide to authentication in the FOSS Package Management System.
Overview¶
The FOSS package system uses custom token-based authentication to secure write operations while keeping read operations public. This allows:
- Public Access: Anyone can search, list, and view packages
- Secure Submissions: Only authenticated users can submit packages
- Flexible Deployment: Easy to enable/disable for development vs production
Quick Start¶
1. Generate Token¶
Example output:
2. Configure API Server¶
Set the token(s) on the API server:
# Single token
export FOSS_API_TOKENS="x7jK9mN2pQ4rT8vW1yZ3bD5fH6gJ8kL0nM2oP4qR6sT8uV0wX2yZ4aB6cD8eF0g"
# Multiple tokens (comma-separated)
export FOSS_API_TOKENS="token1,token2,token3"
Start the API server:
3. Configure CLI¶
Set your token:
Architecture¶
Token Flow¶
graph LR
Client["Client<br/>(CLI/Web)"] -->|X-API-Key| API["API<br/>Server"]
API -->|Validate| Token["Token<br/>Manager"]
Token -->|Allow/Deny| Resource["Protected<br/>Resource"]
Client -->|Request| Resource
Security Model¶
| Operation | Auth Required | Reason |
|---|---|---|
| GET /packages | ❌ No | Public package discovery |
| GET /packages/{name} | ❌ No | View package details |
| GET /security/scans | ❌ No | Security transparency |
| GET /licenses | ❌ No | License information |
| POST /packages | ✅ Yes | Prevent spam/abuse |
| Approve/Reject | ✅ Yes | Administrative action |
API Authentication¶
Using cURL¶
# Set token
export FOSS_API_TOKEN="your-token"
# Submit package
curl -X POST http://localhost:8000/api/v1/packages \
-H "Content-Type: application/json" \
-H "X-API-Key: $FOSS_API_TOKEN" \
-d '{
"name": "requests",
"version": "2.31.0",
"type": "pypi",
"description": "HTTP library"
}'
Using Python¶
import requests
import os
API_TOKEN = os.getenv('FOSS_API_TOKEN')
BASE_URL = "http://localhost:8000/api/v1"
headers = {
'Content-Type': 'application/json',
'X-API-Key': API_TOKEN
}
# Submit package
response = requests.post(
f"{BASE_URL}/packages",
headers=headers,
json={
"name": "flask",
"version": "3.0.0",
"type": "pypi"
}
)
print(response.json())
Using JavaScript¶
const API_TOKEN = process.env.FOSS_API_TOKEN;
const BASE_URL = 'http://localhost:8000/api/v1';
const headers = {
'Content-Type': 'application/json',
'X-API-Key': API_TOKEN
};
// Submit package
const response = await fetch(`${BASE_URL}/packages`, {
method: 'POST',
headers: headers,
body: JSON.stringify({
name: 'express',
version: '4.18.0',
type: 'npm'
})
});
const result = await response.json();
console.log(result);
CLI Authentication¶
Setup¶
# Add to shell config (~/.bashrc, ~/.zshrc, ~/.config/fish/config.fish)
export FOSS_API_TOKEN="your-token"
# Or per-session
export FOSS_API_TOKEN="your-token"
Usage¶
# Submit package (requires auth)
foss-cli submit axios 1.6.2 --type npm
# Alternative: use --token flag
foss-cli --token "your-token" submit axios 1.6.2 --type npm
# Public operations (no auth needed)
foss-cli search axios
foss-cli list
foss-cli info axios
Token Management¶
Multiple Tokens¶
Configure multiple tokens for different services/users:
Benefits:
- Separate tokens per service
- Independent rotation
- Individual revocation
- Usage tracking
Token Rotation¶
Rotate tokens regularly (recommended: every 90 days):
# 1. Generate new token
NEW_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
# 2. Add to server (keep old token for transition)
export FOSS_API_TOKENS="$NEW_TOKEN,$OLD_TOKEN"
# 3. Update clients with new token
export FOSS_API_TOKEN="$NEW_TOKEN"
# 4. After grace period, remove old token
export FOSS_API_TOKENS="$NEW_TOKEN"
Token Storage¶
Development:
# Environment variable (recommended)
export FOSS_API_TOKEN="your-token"
# .env file (with .gitignore)
echo 'FOSS_API_TOKEN="your-token"' >> .env
Production:
# Secrets manager (AWS, Azure, GCP)
aws secretsmanager get-secret-value --secret-id foss-api-token
# Kubernetes secret
kubectl create secret generic foss-api-token \
--from-literal=token=your-token
# Docker secret
echo "your-token" | docker secret create foss-api-token -
Error Handling¶
401 Unauthorized¶
Error:
Solution:
403 Forbidden¶
Error:
Solution:
# Verify token matches server
echo $FOSS_API_TOKEN
# Contact administrator for valid token
# Check server configuration
Development vs Production¶
Development Mode¶
No authentication required (default):
- All endpoints accessible
- Useful for local testing
- Not recommended for shared environments
Production Mode¶
Authentication enabled:
- Write operations require auth
- Read operations remain public
- Recommended for all deployments
Security Best Practices¶
1. Token Generation¶
✅ DO:
- Use
secrets.token_urlsafe(32)or longer - Generate cryptographically secure tokens
- Use minimum 32 characters
❌ DON'T:
- Use predictable tokens
- Use short tokens (< 32 chars)
- Reuse tokens across environments
2. Token Storage¶
✅ DO:
- Store in environment variables
- Use secrets managers in production
- Add
.envto.gitignore
❌ DON'T:
- Commit tokens to version control
- Share tokens in chat/email
- Store tokens in code
3. Token Rotation¶
✅ DO:
- Rotate every 90 days minimum
- Have rotation procedure documented
- Support multiple tokens during transition
❌ DON'T:
- Use same token forever
- Rotate without grace period
- Forget to update all clients
4. Access Control¶
✅ DO:
- Use different tokens per service
- Use different tokens per environment
- Monitor token usage
❌ DON'T:
- Share single token across all services
- Use production tokens in development
- Ignore suspicious activity
5. Network Security¶
✅ DO:
- Use HTTPS in production
- Deploy behind reverse proxy with SSL
- Enable rate limiting
❌ DON'T:
- Send tokens over HTTP
- Expose API directly to internet
- Skip rate limiting
Monitoring¶
Request Logging¶
The API logs all requests with auth status:
GET /api/v1/packages - Auth: no - Status: 200 - Duration: 0.123s
POST /api/v1/packages - Auth: yes - Status: 201 - Duration: 0.456s
POST /api/v1/packages - Auth: no - Status: 401 - Duration: 0.012s
Check Auth Status¶
Query the API root to see if auth is enabled:
Response:
Troubleshooting¶
Token not working¶
-
Verify token is set:
-
Check server logs:
-
Test with curl:
Different token in each terminal¶
Cause: Token not persisted in shell config
Solution: Add to shell config file
Server not enforcing auth¶
Cause: FOSS_API_TOKENS not set
Solution: Set on server and restart
See Also¶
- REST API Reference - API documentation
- CLI Tool Reference - CLI documentation