Production-ready HTTP server for serving SchemaPin .well-known/schemapin.json endpoints with support for multiple developers, key management, and revocation lists.
- Multiple Developer Support: Serve keys for multiple developers/domains
- Key Management: Upload, rotate, and revoke keys via REST API
- Revocation Lists: Maintain and serve key revocation information
- CORS Support: Browser-compatible with configurable CORS policies
- Rate Limiting: Built-in protection against abuse
- Logging & Monitoring: Comprehensive logging and metrics endpoints
- Docker Support: Easy containerized deployment
- Auto-Discovery: Automatic setup with demo data
- Install Dependencies
pip install -r requirements.txt- Start Server
python well_known_server.py- Test Endpoints
# Health check
curl http://localhost:8000/health
# Get .well-known for specific developer
curl http://localhost:8000/.well-known/schemapin/alice.example.com.json
# List all developers
curl http://localhost:8000/api/developers- Build Image
docker build -t schemapin-server .- Run Container
docker run -p 8000:8000 -v $(pwd)/keys:/app/keys schemapin-server| Endpoint | Method | Description |
|---|---|---|
/.well-known/schemapin/{domain}.json |
GET | Get SchemaPin data for specific domain |
/.well-known/schemapin.json |
GET | Get default SchemaPin data (first enabled developer) |
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/api/developers |
GET | List all developers |
/api/developers/{domain} |
GET | Get developer details |
/api/developers/{domain}/keys |
POST | Upload new key |
/api/developers/{domain}/revoke |
POST | Revoke key |
/api/metrics |
GET | Server metrics |
Server configuration is managed via config.json:
{
"server": {
"host": "0.0.0.0",
"port": 8000,
"debug": true
},
"cors": {
"allow_origins": ["*"],
"allow_credentials": true
},
"developers": {
"example.com": {
"name": "Example Corp",
"contact": "security@example.com",
"enabled": true
}
}
}- server.host: Bind address (default: 0.0.0.0)
- server.port: Port number (default: 8000)
- cors.allow_origins: Allowed CORS origins
- storage.keys_directory: Directory for key storage
- logging.level: Log level (DEBUG, INFO, WARNING, ERROR)
- developers: Pre-configured developer domains
- Configure Domain (in config.json):
{
"developers": {
"newdev.example.com": {
"name": "New Developer",
"contact": "security@newdev.example.com",
"enabled": true
}
}
}- Upload Public Key:
curl -X POST http://localhost:8000/api/developers/newdev.example.com/keys \
-H "Content-Type: application/json" \
-d '{
"public_key_pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
"developer_name": "New Developer",
"contact": "security@newdev.example.com"
}'- Generate New Key Pair:
# Using SchemaPin CLI tools
python -m tools.keygen --type ecdsa --output-dir ./new_keys --developer "New Developer"- Upload New Key:
curl -X POST http://localhost:8000/api/developers/newdev.example.com/keys \
-H "Content-Type: application/json" \
-d @new_key_upload.json- Revoke Old Key:
curl -X POST http://localhost:8000/api/developers/newdev.example.com/revoke \
-H "Content-Type: application/json" \
-d '{
"fingerprint": "sha256:old_key_fingerprint",
"reason": "Key rotation"
}'Revoke a compromised key immediately:
curl -X POST http://localhost:8000/api/developers/example.com/revoke \
-H "Content-Type: application/json" \
-d '{
"fingerprint": "sha256:compromised_key_fingerprint",
"reason": "Security incident"
}'server/
├── well_known_server.py # Main server application
├── config.json # Server configuration
├── requirements.txt # Python dependencies
├── Dockerfile # Docker configuration
├── README.md # This file
├── keys/ # Key storage directory
│ ├── alice.example.com.json
│ ├── bob.example.com.json
│ └── charlie.example.com.json
├── logs/ # Log files
│ └── server.log
└── backups/ # Automatic backups
└── keys_backup_YYYYMMDD.tar.gz
- HTTPS Only: Always use HTTPS in production
- Firewall: Restrict access to management API endpoints
- Authentication: Add authentication for management endpoints
- Rate Limiting: Configure appropriate rate limits
- Monitoring: Set up monitoring and alerting
- Backups: Regular key backup and recovery procedures
- Keys are stored as JSON files in the configured directory
- File permissions should be restricted (600 or 644)
- Consider encrypted storage for sensitive environments
- Regular backups are essential
# Example nginx configuration for HTTPS termination
server {
listen 443 ssl;
server_name schemapin.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Restrict management API
location /api/ {
allow 10.0.0.0/8;
deny all;
proxy_pass http://localhost:8000;
}
}# Basic health check
curl http://localhost:8000/health
# Detailed metrics
curl http://localhost:8000/api/metrics# Monitor access logs
tail -f logs/server.log
# Check for errors
grep ERROR logs/server.log
# Monitor key operations
grep "Key uploaded\|Key revoked" logs/server.logThe /api/metrics endpoint provides:
- Total number of developers
- Enabled developers count
- Developers with active keys
- Total revoked keys
- Server uptime
Configure SchemaPin clients to use your server:
# Python
from schemapin.discovery import PublicKeyDiscovery
discovery = PublicKeyDiscovery(base_url="https://your-server.com")// JavaScript
import { PublicKeyDiscovery } from 'schemapin';
const discovery = new PublicKeyDiscovery({
baseUrl: 'https://your-server.com'
});Override discovery URLs for specific domains:
# Python
discovery.domain_overrides = {
'example.com': 'https://your-server.com/.well-known/schemapin/example.com.json'
}-
Port Already in Use
# Check what's using port 8000 lsof -i :8000 # Use different port uvicorn well_known_server:app --port 8001
-
Permission Denied (Keys Directory)
# Fix permissions chmod 755 keys/ chmod 644 keys/*.json
-
CORS Issues
# Check CORS configuration in config.json # Add specific origins instead of "*" for production
-
Key Validation Errors
# Validate key format openssl pkey -in key.pem -pubin -text -noout
Enable debug logging:
{
"server": {
"debug": true
},
"logging": {
"level": "DEBUG"
}
}# Test all endpoints
python -m pytest tests/
# Manual testing
curl -v http://localhost:8000/.well-known/schemapin/alice.example.com.json{
"server": {
"debug": false,
"reload": false
},
"security": {
"rate_limit": {
"requests_per_minute": 120
}
}
}For high-traffic deployments:
- Load Balancer: Use nginx or similar
- Multiple Instances: Run multiple server instances
- Caching: Add Redis or similar for caching
- Database: Consider database storage for large key sets
- Follow existing code style
- Add tests for new features
- Update documentation
- Test with both Python and JavaScript clients
This server implementation follows the same license as the SchemaPin project.