Data Import
Obtaining an Auth Token
All API endpoints (except GET /api/v1/health) require a Bearer JWT token issued by Keycloak.
The server is configured to validate tokens against:
- Realm:
carbon-mrv - Keycloak URL:
http://{{auth_server}}(default; overridden by theKEYCLOAK_URLenv var) - JWKS endpoint:
{KEYCLOAK_URL}/realms/carbon-mrv/protocol/openid-connect/certs
Pre-configured Users
The realm is bootstrapped from keycloak/carbon-mrv-realm.json when running via Docker Compose. Two users are seeded out of the box:
| Username | Password | Role | Project IDs |
|---|---|---|---|
admin-user | admin | aci | proj1, proj2 |
proponent-user | proponent | proponent | proj1 |
The aci role has full read/write access. The proponent role has scoped read/write access to its assigned projects.
Step 1 — Request a Token (Resource Owner Password Grant)
Use the direct access grant (password) flow against the tcctv-api client.
curl
curl -s -X POST \
http://{{auth_server}}/realms/carbon-mrv/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=tcctv-api" \
-d "client_secret=tcctv-api-secret" \
-d "username=admin-user" \
-d "password=admin"
Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR...",
"expires_in": 300,
"token_type": "Bearer",
...
}
Copy the value of access_token.
Step 2 — Use the Token
Pass the token in the Authorization header on every API request:
TOKEN="eyJhbGciOiJSUzI1NiIsInR..."
curl -s -X PUT http://{{api_server}}/api/v1/records \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"engine","recordId":"abc123","id":"3座","date":"2024-04-01T00:00:00+0800","usage":201}'
One-liner: Fetch and Export Token
export TOKEN=$(curl -s -X POST \
http://{{auth_server}}/realms/carbon-mrv/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=tcctv-api" \
-d "client_secret=tcctv-api-secret" \
-d "username=admin-user" \
-d "password=admin" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token acquired."
Then use $TOKEN in subsequent requests or pass it to the sync CLI (can be found in directory {{project-api-server}}/cmd/synccli):
go run ./cmd/synccli \
--server http://{{api_server}} \
--token "$TOKEN" \
--file /path/to/data.jsonl
Token Claims
The middleware extracts the following claims from the JWT:
| Claim | Source in JWT | Used for |
|---|---|---|
sub | Standard JWT subject | Principal identity |
realm_access.roles | Keycloak realm roles array | Cerbos role-based authz |
project_ids | Custom user attribute (multi-value) | Project-scoped access |
Using a Different User or Environment
| Variable | Default | Override via env var |
|---|---|---|
| Keycloak URL | http://{{auth_server}} | KEYCLOAK_URL |
| Realm | carbon-mrv | KEYCLOAK_REALM |
| Client ID | tcctv-api | n/a (hardcoded in realm) |
| Client Secret | tcctv-api-secret | n/a (hardcoded in realm) |
To add or modify users, edit keycloak/carbon-mrv-realm.json and restart Keycloak with --import-realm, or use the Keycloak Admin Console at http://{{auth_server}}/admin (admin / admin).