Skip to main content

Admin API

The Wallet Backend Admin API provides internal management capabilities for multi-tenant wallet infrastructure. This API allows you to:

  • Manage tenants (create, update, delete)
  • Manage user memberships within tenants
  • Configure credential issuers per tenant
  • Configure verifiers per tenant

Overview

The admin API runs on a separate port (default: 8081) from the main wallet API to ensure it's not accidentally exposed to the public internet.

Base URL

http://localhost:8081/admin

In production, this should only be accessible from your internal network.

Multi-Tenancy Model

The wallet backend supports multiple tenants, each with complete isolation of:

ResourceDescription
UsersEach user belongs to one or more tenants with specific roles
CredentialsStored credentials are scoped to tenants
IssuersCredential issuers available to users in the tenant
VerifiersVerifiers where users can present credentials

Tenant IDs

Tenant IDs must:

  • Be lowercase alphanumeric with hyphens
  • Start with a letter
  • Be 2-50 characters long

Examples: acme-corp, university-demo, test-tenant

API Reference

OpenAPI Specification

The complete OpenAPI 3.0 specification is available at:

You can import this into tools like Swagger UI, Postman, or Insomnia for interactive exploration.


Tenant Management

List All Tenants

GET /admin/tenants

Response:

{
"tenants": [
{
"id": "default",
"name": "Default Tenant",
"display_name": "Default Wallet",
"enabled": true,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}
]
}

Create a Tenant

POST /admin/tenants
Content-Type: application/json

{
"id": "acme-corp",
"name": "ACME Corporation",
"display_name": "ACME Digital Wallet",
"enabled": true
}

Get a Tenant

GET /admin/tenants/{tenantId}

Update a Tenant

PUT /admin/tenants/{tenantId}
Content-Type: application/json

{
"id": "acme-corp",
"name": "ACME Corporation Updated",
"display_name": "ACME Wallet",
"enabled": true
}

Delete a Tenant

DELETE /admin/tenants/{tenantId}
warning

Deleting a tenant removes all associated users, credentials, issuers, and verifiers. The default tenant cannot be deleted.


User Management

Users are associated with tenants through memberships. A user can belong to multiple tenants with different roles.

List Tenant Users

GET /admin/tenants/{tenantId}/users

Response:

{
"users": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}

Add User to Tenant

POST /admin/tenants/{tenantId}/users
Content-Type: application/json

{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"role": "user"
}

Roles:

  • user - Standard user access (default)
  • admin - Administrative access within the tenant

Remove User from Tenant

DELETE /admin/tenants/{tenantId}/users/{userId}

Issuer Management

Issuers define where users can request credentials from. The wallet frontend fetches issuer metadata to display available credentials to users.

How Issuers Work

  1. You register an issuer's URL in the admin API
  2. The wallet frontend fetches metadata from {issuer_url}/.well-known/openid-credential-issuer
  3. Users see available credentials from the issuer in their wallet
  4. Users can initiate credential issuance flows

List Issuers

GET /admin/tenants/{tenantId}/issuers

Response:

{
"issuers": [
{
"id": 1,
"tenant_id": "acme-corp",
"credential_issuer_identifier": "https://issuer.example.com",
"client_id": "wallet-client",
"visible": true
}
]
}

Create an Issuer

POST /admin/tenants/{tenantId}/issuers
Content-Type: application/json

{
"credential_issuer_identifier": "https://issuer.example.com",
"client_id": "wallet-client",
"visible": true
}
FieldRequiredDescription
credential_issuer_identifierYesOpenID4VCI issuer URL
client_idNoOAuth2 client ID for authentication
visibleNoWhether to show in wallet UI (default: true)

Update an Issuer

PUT /admin/tenants/{tenantId}/issuers/{issuerId}
Content-Type: application/json

{
"credential_issuer_identifier": "https://issuer.example.com",
"client_id": "new-client-id",
"visible": true
}

Delete an Issuer

DELETE /admin/tenants/{tenantId}/issuers/{issuerId}

Verifier Management

Verifiers define where users can present their credentials. These are displayed in the wallet UI as presentation destinations.

List Verifiers

GET /admin/tenants/{tenantId}/verifiers

Response:

{
"verifiers": [
{
"id": 1,
"tenant_id": "acme-corp",
"name": "University Portal",
"url": "https://verifier.university.edu"
}
]
}

Create a Verifier

POST /admin/tenants/{tenantId}/verifiers
Content-Type: application/json

{
"name": "University Portal",
"url": "https://verifier.university.edu"
}
FieldRequiredDescription
nameYesHuman-readable verifier name
urlYesURL of the verifier service

Update a Verifier

PUT /admin/tenants/{tenantId}/verifiers/{verifierId}
Content-Type: application/json

{
"name": "Updated Portal Name",
"url": "https://new-verifier.example.com"
}

Delete a Verifier

DELETE /admin/tenants/{tenantId}/verifiers/{verifierId}

Example: Setting Up a New Tenant

Here's a complete example of setting up a new tenant with issuers and verifiers:

# 1. Create the tenant
curl -X POST http://localhost:8081/admin/tenants \
-H "Content-Type: application/json" \
-d '{
"id": "university-demo",
"name": "University Demo",
"display_name": "University Digital Wallet",
"enabled": true
}'

# 2. Add a credential issuer
curl -X POST http://localhost:8081/admin/tenants/university-demo/issuers \
-H "Content-Type: application/json" \
-d '{
"credential_issuer_identifier": "https://issuer.university.edu",
"client_id": "wallet-client",
"visible": true
}'

# 3. Add a verifier
curl -X POST http://localhost:8081/admin/tenants/university-demo/verifiers \
-H "Content-Type: application/json" \
-d '{
"name": "Student Portal",
"url": "https://portal.university.edu"
}'

# 4. List the configuration
curl http://localhost:8081/admin/tenants/university-demo/issuers
curl http://localhost:8081/admin/tenants/university-demo/verifiers

Security Considerations

Important

The admin API has no authentication by default. It should never be exposed to the public internet.

Recommended security measures:

  1. Network isolation: Run the admin API on an internal-only network
  2. Firewall rules: Block external access to port 8081
  3. VPN/Bastion: Access admin API through VPN or bastion hosts
  4. Authentication proxy: Add authentication middleware if needed

Environment Variables

VariableDefaultDescription
WALLET_SERVER_ADMIN_PORT8081Port for the admin API
WALLET_SERVER_ADMIN_HOST127.0.0.1Bind address (use 127.0.0.1 for local-only)

Error Responses

All endpoints return consistent error responses:

{
"error": "Error message describing what went wrong"
}

Common HTTP Status Codes:

CodeDescription
200Success
201Resource created
400Bad request (invalid input)
403Forbidden (e.g., cannot delete default tenant)
404Resource not found
409Conflict (e.g., duplicate tenant ID)
500Internal server error