Class: StandardHealth::EnvSpec
- Inherits:
-
Object
- Object
- StandardHealth::EnvSpec
- Defined in:
- lib/standard_health/env_spec.rb
Overview
DSL for declaring required and recommended environment variables.
Example:
StandardHealth::EnvSpec.define do
mode_alias :deployed, %w[staging preview production]
mode_alias :live, %w[production]
required :SECRET_KEY_BASE
required :APP_ENVIRONMENT, in: %w[staging production]
recommended :SENTRY_DSN, description: "Error tracking DSN"
forbidden :DEMO_MODE_ENABLED, in: :live
required :CSP_REPORT_ONLY, in: :live, expected_value: "false"
group "Singpass / MyInfo" do
required :MYINFO_CLIENT_ID
required :MYINFO_PRIVATE_JWKS,
in: :live,
unless: -> { ENV["MYINFO_MOCK_MODE"].present? }
end
end
Each entry has:
- `name` (Symbol)
- `level` (:required | :recommended | :forbidden)
- `in:` (Array<String>, Symbol, or nil) — when an Array, the entry only
applies while `APP_ENVIRONMENT` matches one of these modes. A Symbol
is resolved against `mode_alias` declarations at audit time. When
omitted, the entry applies to every mode.
- `description:` (String, optional) — human-readable hint surfaced
verbatim by `/diagnostics/env`.
- `consumed_by:` (String or Array<String>, optional) — pointer(s) to
where the value is read in the host app. Surfaced verbatim. When
`audit` is called with `root:`, each path is checked for an
`ENV[...]` / `ENV.fetch(...)` reference to the var; the result is
reported as `consumer:` in the audit row
(`:present`, `:file_missing`, or `:not_referenced`).
- `if:` / `unless:` (Proc, optional) — predicates evaluated at audit
time. When `unless:` returns truthy or `if:` returns falsy the entry
is reported with `status: :not_applicable`.
- `group` (String, optional) — set implicitly by enclosing `group`
block; surfaced verbatim.
- `deprecated:` (Boolean, optional) — flag for staged removal. When
true, the audit row includes `deprecated: true`.
- `sunset_on:` (String/Date, optional) — target removal date.
Surfaced verbatim in audit rows.
- `replacement:` (String, optional) — what to use instead. Surfaced
in audit rows.
- `expected_value:` (String/Symbol/Numeric/Regexp/Array, optional) —
asserts the *value*, not just presence. A present value that does
not match reports `status: :mismatch`. An Array means "any of".
Surfaced in audit rows as `expected_value:` so an operator can see
what was demanded; the actual value is deliberately NEVER surfaced
(env values are frequently secrets).
Defined Under Namespace
Classes: Entry, UnknownModeAlias
Constant Summary collapse
- FORBIDDEN_LEVEL =
Levels whose absence is fine and whose presence is the failure.
:forbidden- VIOLATION_STATUSES =
Statuses that mean the environment is wrong, as opposed to merely advisory (
:should_set) or inapplicable (:not_applicable).Shared by
DiagnosticsController#audit_statusand the opt-inChecks::EnvSpecAudit, so the doctor endpoint and the health check cannot drift apart on what counts as a violation. %i[missing forbidden mismatch].freeze
Instance Attribute Summary collapse
- #entries ⇒ Array<Entry> readonly
- #mode_aliases ⇒ Hash{Symbol => Array<String>} readonly
Class Method Summary collapse
-
.define(&block) ⇒ Object
Build a spec via the DSL.
Instance Method Summary collapse
-
#audit(env_hash, mode:, root: nil) ⇒ Array<Hash>
Run the audit against an env-like hash.
-
#forbidden(name, **opts) ⇒ Object
Declare an env var that must NOT be set (in the applicable modes).
-
#group(label, &block) ⇒ Object
Group subsequent declarations under a label.
-
#initialize ⇒ EnvSpec
constructor
A new instance of EnvSpec.
-
#mode_alias(name, modes) ⇒ Object
Declare a mode alias usable in
in:. -
#recommended(name, **opts) ⇒ Object
Declare a recommended env var.
-
#required(name, **opts) ⇒ Object
Declare a required env var.
Constructor Details
#initialize ⇒ EnvSpec
Returns a new instance of EnvSpec.
103 104 105 106 107 |
# File 'lib/standard_health/env_spec.rb', line 103 def initialize @entries = [] @mode_aliases = {} @group_stack = [] end |
Instance Attribute Details
#entries ⇒ Array<Entry> (readonly)
93 94 95 |
# File 'lib/standard_health/env_spec.rb', line 93 def entries @entries end |
#mode_aliases ⇒ Hash{Symbol => Array<String>} (readonly)
96 97 98 |
# File 'lib/standard_health/env_spec.rb', line 96 def mode_aliases @mode_aliases end |
Class Method Details
.define(&block) ⇒ Object
Build a spec via the DSL.
99 100 101 |
# File 'lib/standard_health/env_spec.rb', line 99 def self.define(&block) new.tap { |spec| spec.instance_eval(&block) if block } end |
Instance Method Details
#audit(env_hash, mode:, root: nil) ⇒ Array<Hash>
Run the audit against an env-like hash.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/standard_health/env_spec.rb', line 193 def audit(env_hash, mode:, root: nil) mode_str = mode.to_s env = stringify(env_hash) @entries.each_with_object([]) do |entry, out| next unless mode_applies?(entry, mode_str) row = base_row(entry, mode_str) suppression = predicate_suppression(entry) if suppression row[:status] = :not_applicable row[:reason] = suppression else value = env[entry.name.to_s] row[:status] = classify(entry, value) end consumer_status = consumer_state(entry, root) row[:consumer] = consumer_status if consumer_status out << row end end |
#forbidden(name, **opts) ⇒ Object
Declare an env var that must NOT be set (in the applicable modes).
Inverts the presence rule: absent is :ok, present is :forbidden.
This is the level for dangerous ops toggles — demo modes, auth bypasses, bootstrap flags — that are legitimate on staging and must never survive to production:
forbidden :DEMO_MODE_ENABLED, in: :live,
description: "Demo surfaces; unset before promoting"
expected_value: is meaningless here (the assertion is "absent"), so
combining them is a declaration error rather than a silently ignored
option. Raised at define time — i.e. host boot, well off the health
path — so it can never surface as a 500 from /ready.
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/standard_health/env_spec.rb', line 165 def forbidden(name, **opts) if opts.key?(:expected_value) raise ArgumentError, "`forbidden` asserts absence, so expected_value: is meaningless " \ "(got #{opts[:expected_value].inspect} for #{name}). Use " \ "`required ..., expected_value:` to assert a value instead." end add(FORBIDDEN_LEVEL, name, **opts) end |
#group(label, &block) ⇒ Object
Group subsequent declarations under a label. Pure metadata —
propagated to audit rows as group: and otherwise inert. Nested
group blocks are supported; the innermost label is the one that
propagates to enclosed entries.
124 125 126 127 128 129 130 131 |
# File 'lib/standard_health/env_spec.rb', line 124 def group(label, &block) raise ArgumentError, "group requires a block" unless block @group_stack.push(label.to_s) block.call ensure @group_stack.pop end |
#mode_alias(name, modes) ⇒ Object
Declare a mode alias usable in in:. Re-declaring overrides the
previous value (last writer wins) so layered specs are easy to compose.
114 115 116 |
# File 'lib/standard_health/env_spec.rb', line 114 def mode_alias(name, modes) @mode_aliases[name.to_sym] = Array(modes).map(&:to_s) end |
#recommended(name, **opts) ⇒ Object
Declare a recommended env var. A missing value never fails the audit;
it surfaces as :should_set.
147 148 149 |
# File 'lib/standard_health/env_spec.rb', line 147 def recommended(name, **opts) add(:recommended, name, **opts) end |
#required(name, **opts) ⇒ Object
Declare a required env var.
141 142 143 |
# File 'lib/standard_health/env_spec.rb', line 141 def required(name, **opts) add(:required, name, **opts) end |