Cross-Service References
References let one service or addon read another’s values without copy-pasting credentials. They keep secrets in one place and rotate automatically.
Syntax
${{<name>.<KEY>}}<name>— the target service or addon name (the one shown in the dashboard and used inlizard add -n).<KEY>— a key in the target’s merged environment.
Use them anywhere a value is accepted — most commonly in a secret:
lizard secrets set DATABASE_URL='${{postgres.DATABASE_URL}}' --service apiHow they resolve
- References resolve at deploy time against the target’s merged environment.
- They’re stored by ID, so renaming the target later doesn’t break the reference.
- A reference to a missing target or key resolves to an empty string — it does not fail the deploy.
- Only circular references throw an error.
Because a missing key silently becomes empty, always verify the consumer actually received the value after wiring a reference:
lizard ssh --service api -- env | grep DATABASE_URL
Common patterns
Wire an addon to several services — bind on each consumer so rotation propagates everywhere:
lizard secrets set REDIS_URL='${{redis.REDIS_URL}}' --service api
lizard secrets set REDIS_URL='${{redis.REDIS_URL}}' --service workerReference another service’s value — e.g. share a computed URL or token:
lizard secrets set UPSTREAM_URL='${{api.LIZARD_PUBLIC_DOMAIN}}' --service webReference a second addon of the same type — use its generated name:
lizard secrets set CACHE_URL='${{redis-winter-otter.REDIS_URL}}' --service apiWhy not just use --global?
Putting a shared DSN in project (--global) scope exposes it to every service, including ones that don’t need it. References give you the same single-source-of-truth rotation while keeping each secret scoped to the services that actually consume it. See Secret scoping.