A Rust-based gateway service for managing IPv6 prefix leases and ASN assignments for the PeerLab project. This service allows authenticated users to request ASN assignments and time-limited IPv6 /48 prefix leases, and provides endpoints for downstream services to query user-to-prefix mappings.
- ASN Management: Users can request and maintain ASN assignments
- Prefix Leasing: Time-based IPv6 /48 prefix allocation from a configurable pool
- JWT Authentication: Secure API access using Auth0 JWT tokens
- Agent Authentication: Service API endpoints protected with Bearer token authentication
- Email Retrieval: On-demand email fetching from Auth0 Management API (no email storage)
- PostgreSQL Storage: Persistent storage of user mappings and lease information
- Service API: Authenticated endpoints for downstream services to query user mappings
The service provides two main API surfaces:
- Client API (
/api/*): JWT-authenticated endpoints for end users via nxthdr.dev - Service API (
/service/*): Agent-authenticated endpoints for downstream services to query mappings (requires Bearer token)
Get user information including ASN and active prefix leases.
Response:
{
"user_hash": "abc123...",
"asn": 65001,
"active_leases": [
{
"prefix": "2001:db8:1000::/48",
"start_time": "2025-01-01T00:00:00Z",
"end_time": "2025-01-01T01:00:00Z"
}
]
}Request an ASN assignment. The gateway automatically assigns an available ASN from the pool. Once assigned, the same ASN is always returned for the user.
Request: No body required
Response:
{
"asn": 65001,
"message": "ASN assigned successfully"
}Request a time-limited IPv6 /48 prefix lease.
Request:
{
"duration_hours": 1
}Response:
{
"prefix": "2001:db8:1000::/48",
"start_time": "2025-01-01T00:00:00Z",
"end_time": "2025-01-01T01:00:00Z",
"message": "Prefix leased successfully"
}All service API endpoints require agent authentication using a Bearer token in the Authorization header.
Authentication Header:
Authorization: Bearer <agent-key>
Get all user mappings with ASN, active prefixes, and email addresses.
Response:
{
"mappings": [
{
"user_hash": "abc123...",
"user_id": "auth0-user-id",
"email": "[email protected]",
"asn": 65001,
"prefixes": ["2001:db8:1000::/48"]
}
]
}Note: The email field is fetched on-demand from Auth0 Management API and is not stored in the database. It will be null if Auth0 M2M credentials are not configured or if the user doesn't have an email.
Get mapping for a specific user.
Response:
{
"user_hash": "abc123...",
"user_id": "auth0-user-id",
"email": "[email protected]",
"asn": 65001,
"prefixes": ["2001:db8:1000::/48"]
}--address: API listen address (default:0.0.0.0:8080)--database-url: PostgreSQL connection URL (default:postgresql://localhost/peerlab_gateway)--prefix-pool-file: Path to prefix pool file (default:prefixes.txt)--asn-pool-start: ASN pool start (default:65000)--asn-pool-end: ASN pool end (default:65999, provides 1000 ASNs)
--auth0-jwks-uri: Auth0 JWKS URI for JWT validation--auth0-issuer: Auth0 issuer for JWT validation--bypass-jwt: Bypass JWT validation (development only)
--agent-key: Agent key for service API authentication (default:agent-key)
--auth0-management-api: Auth0 Management API URL (e.g.,https://your-instance.auth0.app)--auth0-m2m-app-id: Auth0 M2M application ID for Management API access--auth0-m2m-app-secret: Auth0 M2M application secret for Management API access
Note: Email retrieval is optional. If M2M credentials are not provided, the email field in service API responses will be null.
Create a prefixes.txt file with one /48 IPv6 prefix per line:
2001:db8:1000::/48
2001:db8:1001::/48
2001:db8:1002::/48
Lines starting with # are treated as comments. See prefixes.txt.example for a template.
The service uses PostgreSQL with two main tables:
Stores the mapping between users and their assigned ASN.
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| user_hash | VARCHAR(64) | SHA256 hash of user identifier (unique) |
| user_id | VARCHAR(255) | Auth0 user ID for email retrieval (nullable) |
| asn | INTEGER | Assigned ASN (unique) |
| created_at | TIMESTAMP | Creation timestamp |
| updated_at | TIMESTAMP | Last update timestamp |
Stores time-limited prefix leases.
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| user_hash | VARCHAR(64) | SHA256 hash of user identifier |
| prefix | CIDR | Leased IPv6 prefix |
| start_time | TIMESTAMP | Lease start time |
| end_time | TIMESTAMP | Lease expiration time |
| created_at | TIMESTAMP | Creation timestamp |
| updated_at | TIMESTAMP | Last update timestamp |
- Rust 1.70 or later
- PostgreSQL 14 or later
cargo build --release- Start PostgreSQL:
docker run -d --name peerlab-postgres \
-e POSTGRES_DB=peerlab_gateway \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16- Create prefix pool file:
cp prefixes.txt.example prefixes.txt- Run the service:
cargo run -- \
--database-url postgresql://postgres:postgres@localhost/peerlab_gateway \
--prefix-pool-file prefixes.txt \
--bypass-jwtRun unit tests:
cargo testRun integration tests (requires Docker):
cd integration
docker compose up -d --force-recreate --renew-anon-volumes
./tests/test_gateway.sh
docker compose downSee integration/README.md for manual testing and troubleshooting.
Build the Docker image:
docker build -t peerlab-gateway .Run the container:
docker run -d \
-p 8080:8080 \
-v $(pwd)/prefixes.txt:/app/prefixes.txt \
-e DATABASE_URL=postgresql://user:pass@host/db \
peerlab-gateway \
--database-url $DATABASE_URL \
--prefix-pool-file /app/prefixes.txt \
--auth0-jwks-uri https://your-auth0.com/.well-known/jwks.json \
--auth0-issuer https://your-auth0.comThe nxthdr.dev frontend should:
- Authenticate users via Auth0 and obtain JWT tokens
- Call
POST /api/user/asnto request an ASN (if not already assigned) - Call
POST /api/user/prefixto request prefix leases with desired duration - Call
GET /api/user/infoto display current ASN and active leases
Downstream services (e.g., BGP configuration generators, BIRD config generators) must authenticate using an agent key.
All service API requests must include the agent key in the Authorization header:
curl -H "Authorization: Bearer <agent-key>" \
https://gateway.example.com/service/mappingsDownstream services can:
- Call
GET /service/mappingsto get all current user-to-ASN-to-prefix mappings with email addresses - Call
GET /service/mappings/:user_hashto query specific user mappings - Poll these endpoints periodically to stay synchronized with active leases
The service API returns:
user_hash: SHA256 hash of the user identifieruser_id: Auth0 user IDemail: User's email address (fetched from Auth0 on-demand, may benull)asn: Assigned ASNprefixes: List of active IPv6 /48 prefixes
See LICENSE file for details.