Dev Mode Access
dev-mode-access.conf is loaded when the dev-mode feature is enabled in _features.conf. It is a
second, independent gate on top of the dev-mode flag: enabling dev-mode alone no longer makes the /v1/dev/*
endpoints (initial-setup, database-recreate, add-example-data, webhook-test) reachable. Every request to
those endpoints must also include a matching X-Dev-Mode-Token header.
/v1/dev/* includes destructive, unauthenticated-by-design endpoints (dropping and reseeding the database, among
others). Never enable dev-mode on a deployment reachable outside a trusted network, even with accessToken set —
treat this as a convenience for local/CI use, not a security boundary on its own.
Example File
This is exactly the shipped template - commented out, so dev-mode stays non-functional until you act on it:
# accessToken = "replace-with-a-per-deployment-secret"
Fields
accessToken
String, optional — defaults to unset (null). This is deliberately fail-closed: if the dev-mode feature is
enabled but accessToken is unset, /v1/dev/* refuses every request with 503 Service Unavailable, rather than
falling back to open access. A startup warning is logged in this case as well.
Startup refuses to proceed at all if accessToken is set to the literal placeholder above,
"replace-with-a-per-deployment-secret". That exact string is published in walt.id's own source and documentation,
so uncommenting the template without changing it provides no protection - the check exists specifically to catch
that. Replace it with a real, secret, per-deployment value.
Once set, every call to /v1/dev/* must include a matching header:
curl -X POST http://localhost:3000/v1/dev/database-recreate \
-H 'X-Dev-Mode-Token: <your accessToken value>'
A missing or mismatched header returns 401 Unauthorized. The header is also documented as a request parameter in
Swagger, so it can be set directly from the "Try it out" panel for each /v1/dev/* operation.
Use a real, secret, per-deployment value for anything beyond local/CI use. A shared or well-known value provides no protection on its own, the same way an unset value provides none.
