Module: LocalVault::PlaintextOutput
- Defined in:
- lib/localvault/plaintext_output.rb
Overview
Gate for printing plaintext secret values.
Plaintext may flow to an interactive terminal (a human is watching). When stdout is captured (pipe, command substitution, agent shell), a human can confirm with one keystroke on /dev/tty. An agent's shell has no /dev/tty, and there is deliberately no flag, environment variable, or config bypass: anything discoverable from the binary would be discovered by an agent.
Constant Summary collapse
- TTY_PATH =
"/dev/tty".freeze
Class Attribute Summary collapse
-
.assume_tty ⇒ Object
In-process overrides for tests only — unreachable from the installed binary, unlike an env var or CLI flag would be.
-
.tty_override ⇒ Object
IO, output: IO.
Class Method Summary collapse
- .confirm(prompt) ⇒ Object
-
.permitted?(out: $stdout, purpose: "Print plaintext") ⇒ Boolean
Whether plaintext may be printed to
out. - .with_tty(&block) ⇒ Object
Class Attribute Details
.assume_tty ⇒ Object
In-process overrides for tests only — unreachable from the installed binary, unlike an env var or CLI flag would be.
15 16 17 |
# File 'lib/localvault/plaintext_output.rb', line 15 def assume_tty @assume_tty end |
.tty_override ⇒ Object
IO, output: IO
16 17 18 |
# File 'lib/localvault/plaintext_output.rb', line 16 def tty_override @tty_override end |
Class Method Details
.confirm(prompt) ⇒ Object
29 30 31 32 33 34 35 36 |
# File 'lib/localvault/plaintext_output.rb', line 29 def self.confirm(prompt) with_tty do |input, output| output.write(prompt) output.flush answer = input.gets !answer.nil? && %w[y yes].include?(answer.strip.downcase) end end |
.permitted?(out: $stdout, purpose: "Print plaintext") ⇒ Boolean
Returns whether plaintext may be printed to out.
22 23 24 25 26 27 |
# File 'lib/localvault/plaintext_output.rb', line 22 def self.permitted?(out: $stdout, purpose: "Print plaintext") return true if assume_tty return true if out.respond_to?(:tty?) && out.tty? confirm("#{purpose}? [y/N] ") end |
.with_tty(&block) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'lib/localvault/plaintext_output.rb', line 38 def self.with_tty(&block) if tty_override return yield(tty_override[:input], tty_override[:output]) end File.open(TTY_PATH, "r+") { |tty| yield(tty, tty) } rescue SystemCallError, IOError false end |