A Go-based microservices backend for issuing and verifying digital credentials, originally created within the DC4EU (Digital Credentials for Europe) project.
The platform implements the OpenID4VCI and OpenID4VP protocols to issue and verify credentials in SD-JWT VC, W3C Verifiable Credentials 2.0, and ISO/IEC 18013-5 mdoc formats.
# 1. Generate development PKI certificates
make pki
# 2. Start all services (MongoDB + microservices)
make start
# 3. Verify everything is running
docker compose psThe services will be available on the internal Docker network (172.16.50.0/24):
| Service | Address |
|---|---|
| API Gateway | http://apigw.vc.docker:8080 |
| UI | http://ui.vc.docker:8080 |
| Issuer | http://issuer.vc.docker:8080 |
| Verifier | http://verifier.vc.docker:8080 |
| Registry | http://registry.vc.docker:8080 |
| Mock AS | http://mockas.vc.docker:8080 |
| MongoDB | mongodb://mongo.vc.docker:27017 |
To access a service from the host, use its container IP directly (e.g. http://172.16.50.2:8080 for apigw) or publish ports in docker-compose.yaml.
To stop everything: make stop
A minimal config file is provided at config_minimal.yaml for getting started with sensible defaults. To use it, set the environment variable before starting:
export VC_CONFIG_YAML=config_minimal.yamlThe full configuration with all options is in config.yaml. See docs/CONFIGURATION.md for details.
- Docker and Docker Compose
- GNU Make
| Service | Description |
|---|---|
| apigw | API Gateway with optional SAML and OIDC RP support for relying party integration |
| issuer | Issues verifiable credentials via OpenID4VCI with VCTM schema validation |
| verifier | Verifies credential presentations via OpenID4VP, DCQL, and the W3C Digital Credentials API |
| registry | Credential registry and status list management |
| mockas | Mock Authorization Server for development and testing |
| ui | Web UI for credential issuance and presentation |
A relying party (e.g. Keycloak) connects to the Verifier as a standard OIDC Provider. The Verifier translates the OIDC request into an OpenID4VP presentation request toward the wallet.
ββββββββββββββ OIDC ββββββββββββββββββββββββββββ
β Relying β βββββββββββββββββββββββΊ β VERIFIER β
β Party β authorize, token, β β
β (Keycloak) β userinfo β OIDC Provider (OP) β
ββββββββββββββ βββββββββββββββββββββββ β OpenID4VP Verifier β
ββββββββββββββ¬ββββββββββββββ
β
β OpenID4VP
β (present credential)
βΌ
ββββββββββββββββββββββββββββ
β WALLET β
β (phone app) β
ββββββββββββββββββββββββββββ
PID issuance and non-PID issuance follow different authentication paths
determined by auth_method in the credential configuration.
Wallet requests credential
via OpenID4VCI (PAR β Authorize)
β
ββββββββββββββ΄βββββββββββββ
β β
auth_method: basic auth_method: pid_auth
β β
ββββββββββββΌβββββββββββ ββββββββββββΌββββββββββββββββ
β PATH 1: PID β β PATH 2: OTHER β
β (pid_1_5, pid_1_8) β β (ehic, diploma, pda1, β
β β β elm, eduid, micro...) β
β User authenticates β β β
β via external IdP: β β Wallet presents existing β
β β β PID credential back to β
β β’ SAML IdP β β APIGW via OpenID4VP β
β β’ OIDC Provider β β β
β β’ Username/Pass β β APIGW verifies PID, β
β (dev/test) β β extracts identity, looks β
β β β up document in datastore β
ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββββββββ
β β
ββββββββββββββ¬βββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β APIGW β
β OAuth AS (OpenID4VCI) β
β Consent β Token β β
β Credential β
βββββββ¬βββββββββββββββ¬βββββββ
β gRPC β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β ISSUER β β REGISTRY β
β β β β
β Signs cred β β Token β
β (SD-JWT VC, β β Status List β
β mdoc, β β (revocation)β
β W3C VC) β β β
ββββββββββββββββ ββββββββββββββββ
ββββββββββββββ
β SAML IdP / β
ββββββββββββββ β OIDC IdP β
β Relying β β (external) β
β Party β ββββββββ¬ββββββ
β (Keycloak) β β
βββββββ¬βββββββ SAML / OIDC RP β
β OIDC (PID issuance auth) β
βΌ β
ββββββββββββββββββββ OpenID4VP ββββββββββββββββ β
β VERIFIER β ββββββββββββββββββββββββ β β β
β β (present credential) β β β
β OIDC Provider β ββββββββββββββββββββββββΊ β WALLET β β
β OpenID4VP β (request presentation) β (phone app) β β
ββββββββββββββββββββ β β β
β β β
OpenID4VCI β β β
(receive new credential) β β β
ββββββββββββββββββββββββββββββββββββββββ€ β β
β OpenID4VP β β β
β (present PID for non-PID issue) β β β
β βββββββββββββββββββββββββββββββββββββ€ β β
β β ββββββββββββββββ β
βΌ βΌ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β APIGW β β
β ββββββ
β OAuth AS (OpenID4VCI) β issue credentials to wallet β
β OpenID4VP Verifier β verify PID before non-PID issuance β
β SAML SP (optional) β authenticate for PID issuance β
β OIDC RP (optional) β authenticate for PID issuance β
ββββββββββββ¬βββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββ
β gRPC β
βΌ βΌ
ββββββββββββββββββββ ββββββββββββββββββββ
β ISSUER β β REGISTRY β
β Signs creds β β Token Status β
β (SD-JWT VC, β β List β
β mdoc, W3C VC) β β (revocation) β
ββββββββββββββββββββ ββββββββββββββββββββ
ββββββββββββββββββββ ββββββββββββββββββββ
β UI β β MOCK AS β
β Admin web ββββββββββββΊβ Test users & β
β interface β β bootstrapping β
ββββββββββββββββββββ ββββββββββββββββββββ
| Component | Server Role | Client Role |
|---|---|---|
| Verifier | OIDC Provider (OP) toward relying parties | OpenID4VP verifier toward wallets |
| APIGW | OAuth AS (OpenID4VCI) toward wallets | SAML SP + OIDC RP toward external IdPs (PID issuance) |
| OpenID4VP verifier (non-PID issuance auth) | ||
| Issuer | gRPC credential signing service | β |
| Registry | Token Status List (revocation) | β |
- Issue verifiable credentials via OpenID4VCI 1.0
- Verify credential presentations via OpenID4VP 1.0 with
direct_postresponse mode - SD-JWT VC (draft-ietf-oauth-sd-jwt-vc-13), W3C Verifiable Credentials 2.0, and ISO/IEC 18013-5 mdoc credential formats
- Browser-native credential presentation via the W3C Digital Credentials API (
navigator.credentials.get()) - DCQL (Digital Credentials Query Language) for flexible presentation requests
- Credential revocation via Token Status List (draft-ietf-oauth-status-list) with JWT (RFC 7519) and CWT (RFC 8392) formats
- VCTM schema validation before credential issuance (draft-ietf-oauth-sd-jwt-vc-13 Β§6)
- PKCS#11 / HSM support for hardware-backed key protection
- SAML 2.0, OpenID Connect Core 1.0, and OAuth 2.0 Relying Party authentication with PKCE (RFC 7636), DPoP (RFC 9449), and JAR (RFC 9101)
- gRPC inter-service communication
- Kafka-based message brokering
- MongoDB storage backend
- OpenTelemetry distributed tracing
- Static Linux/amd64 binaries for containerized deployment
latest tracks the latest tag available and is built from branch main.
main is the stable development branch.
| Service | Command | Description |
|---|---|---|
| All | make build |
Build all services |
| apigw | make build-apigw |
API Gateway |
| issuer | make build-issuer |
Credential Issuer |
| verifier | make build-verifier |
Credential Verifier |
| registry | make build-registry |
Registry |
| mockas | make build-mockas |
Mock Authentication Service |
| ui | make build-ui |
Web UI |
| vc20-test-server | make build-vc20-test-server |
W3C VC 2.0 test server |
All standard builds produce static binaries (CGO_ENABLED=0) for linux/amd64. Output goes to ./bin/.
Optional features are enabled via Go build tags. The following tags are available:
| Tag | Description | Affected service(s) | CGO | Make target |
|---|---|---|---|---|
saml |
SAML IdP support | apigw | static | make build-apigw-saml |
oidcrp |
OpenID Connect Relying Party | apigw | static | make build-apigw-oidcrp |
saml,oidcrp |
All optional apigw features | apigw | static | make build-apigw-all |
pkcs11 |
PKCS#11 HSM signing | issuer | dynamic | make build-issuer-hsm |
vc20 |
W3C Verifiable Credentials 2.0 | vc20-test-server | static | make build-vc20-test-server |
Note: The
pkcs11tag requires CGO (CGO_ENABLED=1) and produces a dynamically linked binary.
For convenience all services can be built inside a Docker container.
| Command | Description |
|---|---|
make docker-build |
Build all Docker images |
make docker-build-<service> |
Build a specific service image |
make docker-build-apigw-saml |
apigw image with SAML support |
make docker-build-apigw-oidcrp |
apigw image with OIDC RP support |
make docker-build-apigw-all |
apigw image with all features |
make docker-build-issuer-hsm |
issuer image with PKCS#11 HSM support |
make docker-push |
Push all standard images to registry |
make docker-push-apigw-saml |
Push apigw SAML image |
make docker-push-apigw-oidcrp |
Push apigw OIDC RP image |
make docker-push-apigw-all |
Push apigw all-features image |
make docker-push-issuer-hsm |
Push issuer HSM image |
make docker-tag |
Tag all images |
Set the image version with VERSION=x.x.x (default: latest).
| Command | Description |
|---|---|
make start |
Start all services via docker-compose |
make stop |
Stop all services |
make restart |
Restart all services |
make pki |
Generate PKI infrastructure |
make pki-clean |
Remove PKI material |
| Command | Description |
|---|---|
make test |
Run all service tests |
make test-saml |
Test with saml build tag |
make test-oidcrp |
Test with oidcrp build tag |
make test-vc20 |
Test with vc20 build tag |
make test-pkcs11 |
Test with pkcs11 build tag (requires make test-env) |
make test-all-tags |
Test with all build tags |
make test-env |
Install test dependencies (softhsm2, opensc) |
| Command | Description |
|---|---|
make install-tools |
Install protoc, swag, and Go gRPC plugins |
make vscode |
Full VS Code dev environment setup |
make proto |
Regenerate protobuf files |
make swagger |
Regenerate Swagger documentation |
make gosec |
Run security scanner |
make staticcheck |
Run static analysis |
make vulncheck |
Run vulnerability checker |
GET http://<apigw-url>/swagger/doc.json
or with web browser: http://<apigw-url>/swagger/index.html