Security
vdb renders your full database schema. That is sensitive information. This page covers the recommended practices for keeping it safe.
Development-only mounting
The simplest and most robust guard is to only mount the engine in development:
# config/routes.rb
Rails.application.routes.draw do
if Rails.env.development?
mount Vdb::Engine, at: '/dev/erd'
end
# …
end
This means the route does not exist at all in staging or production — no auth bypass possible.
HTTP Basic Auth
If you need the ERD accessible on a non-local environment (e.g. a shared staging server), enable Basic Auth via the config:
# config/initializers/vdb.rb
return unless Rails.env.development? || Rails.env.staging?
Vdb.configure do |c|
c.username = ENV.fetch('VDB_USER')
c.password = ENV.fetch('VDB_PASS')
end
Both values must be non-nil for auth to activate. The comparison uses ActiveSupport::SecurityUtils.secure_compare — a constant-time string comparison that prevents timing attacks.
Environment variable setup
Set the credentials as environment variables — never commit them to source control:
# .env (never commit this file)
VDB_USER=admin
VDB_PASS=a-long-random-secret-string
# Or export directly in your shell
export VDB_USER=admin
export VDB_PASS=a-long-random-secret-string
Content Security Policy
vdb loads D3.js and Stimulus from jsDelivr CDN. If your app enforces a strict CSP, you need to permit these sources for script-src:
# config/initializers/content_security_policy.rb
Rails.application.configure do
config.content_security_policy do |policy|
policy.script_src :self,
'https://cdnjs.cloudflare.com' # highlight.js (docs only)
# vdb loads from jsDelivr:
policy.script_src_attr :none
policy.script_src_elem :self,
'https://cdn.jsdelivr.net'
end
end
Rails.env.development? blocks so production CSP stays strict.
What data is exposed
vdb reads only db/schema.rb (or the configured schema files). It never:
- Queries the database
- Reads table contents or row counts
- Accesses Rails credentials, secrets, or environment variables
- Makes outbound HTTP requests (schema is read from disk)
The schema file itself reveals:
- Table and column names
- Column types and null constraints
- Index definitions (including unique indexes)
- Foreign-key declarations
This is enough to understand your entire data model. Treat it accordingly.
Security checklist
| Environment | Recommended setup |
|---|---|
| Local development | No auth needed. Default config is sufficient. |
| Shared / remote development | Enable Basic Auth via env vars. Use HTTPS. |
| Staging | Use Basic Auth + environment guard. Or skip mounting entirely. |
| Production | Do not mount. Wrap mount in if Rails.env.development?. |