A very fast and resource-efficient pseudonym service.
Supports horizontal service replication for highly-available deployments.
Documentation: https://miracum.github.io/vfps/
Warning This stack is for trying vfps out, not for keeping data: it uses a well-known database password, stores everything in an anonymous volume, and has authentication turned off. See Production deployment to run vfps for real.
With Docker Compose 2.34 or later, and without cloning this repository:
docker compose -f oci://ghcr.io/miracum/vfps/compose/getting-started:v1.22.4 upFrom a checkout, docker compose -f compose.yaml --profile=test up starts the same services.
Visit http://localhost:8080/swagger to view the OpenAPI specification of the Vfps API:
You can use the JSON-transcoded REST API described via OpenAPI or interact with the service using gRPC. For example, using grpcurl to create a new namespace:
grpcurl \
-plaintext \
-d '{"name": "test", "pseudonymGenerationMethod": "PSEUDONYM_GENERATION_METHOD_SECURE_RANDOM_BASE64URL_ENCODED", "pseudonymLength": 32}' \
127.0.0.1:8081 \
vfps.api.v1.NamespaceService/CreateAnd to create a new pseudonym inside this namespace:
grpcurl \
-plaintext \
-d '{"namespace": "test", "originalValue": "to be pseudonymized"}' \
127.0.0.1:8081 \
vfps.api.v1.PseudonymService/Create- Namespaces with a choice of pseudonym formats, multi-level (parent/child) namespaces, and multiple pseudonyms per original value
- Deterministic, oblivious VOPRF pseudonyms (RFC 9497) from a separate key holder
- gRPC, JSON-transcoded REST, and FHIR operations
- An admin UI with CSV pseudonymization jobs
- OIDC sign-in, namespace-scoped access control, and vfps-issued access tokens
- A Helm chart for production deployments, with TLS to PostgreSQL and an encrypted Data Protection key ring
- OpenTelemetry metrics and traces
- Signed container images with SLSA Level 3 provenance - see Security
All settings are listed in the configuration reference.
- .NET 10.0: https://dotnet.microsoft.com/en-us/download/dotnet
- Docker CLI 20.10.17: https://www.docker.com/
- Docker Compose: https://docs.docker.com/compose/install/
Start an empty PostgreSQL database, Keycloak, and SeaweedFS for development (optionally add -d to run in the background):
docker compose -f compose.yaml --profile=keycloak --profile=s3 upTo additionally start an instance of Jaeger Tracing, you can specify the jaeger
profile:
docker compose -f compose.yaml --profile=jaeger upThen set Tracing__IsEnabled=true and Tracing__Otlp__Endpoint=http://localhost:4317 (already the default in
appsettings.Development.json) and view traces at http://localhost:16686.
Restore dependencies and run in Debug mode:
dotnet restore
dotnet run -c Debug --project=src/VfpsOpen https://localhost:8080/ui to see the admin UI, and https://localhost:8080/swagger to see the OpenAPI UI for the JSON-transcoded gRPC services. You can use grpcurl to interact with the API:
Note The server offers gRPC reflection, so grpcurl needs no
.protofiles.
grpcurl -plaintext \
-d '{"name": "test", "pseudonymGenerationMethod": "PSEUDONYM_GENERATION_METHOD_SECURE_RANDOM_BASE64URL_ENCODED", "pseudonymLength": 32}' \
127.0.0.1:8081 \
vfps.api.v1.NamespaceService/Create
grpcurl -plaintext \
-d '{"namespace": "test", "originalValue": "a test value"}' \
127.0.0.1:8081 \
vfps.api.v1.PseudonymService/Createdotnet test src/Vfps.Tests \
--configuration=Release \
--results-directory=./coverage \
-- --coverage \
--coverage-output-format cobertura \
--coverage-output coverage.cobertura.xml \
--coverage-settings src/Vfps.Tests/codecoverage.configIf not installed, install the report generation too:
dotnet tool install -g dotnet-reportgenerator-globaltoolreportgenerator -reports:"./coverage/coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:Htmldocker build -t ghcr.io/miracum/vfps:latest .uv run zensical serve