Class: Seekrit::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/seekrit/client.rb

Overview

A read-only seekrit client bound to one service token. A service token selects exactly one app environment (plus its composed group slices).

client = Seekrit::Client.new           # token from ENV["SEEKRIT_TOKEN"]
secrets = client.resolve               # { "DATABASE_URL" => "...", ... }

Constant Summary collapse

DEFAULT_API_URL =
"https://api.seekrit.dev"

Instance Method Summary collapse

Constructor Details

#initialize(token: nil, api_url: nil, with: {}, open_timeout: 10, read_timeout: 30, interpolate: true) ⇒ Client

Returns a new instance of Client.

Parameters:

  • token (String, nil) (defaults to: nil)

    skt_... service token; defaults to ENV.

  • api_url (String, nil) (defaults to: nil)

    API base URL; defaults to ENV or the hosted API.

  • with (Hash) (defaults to: {})

    => env_slug overrides (the ?with= override).

  • open_timeout (Numeric) (defaults to: 10)

    connection timeout, seconds.

  • read_timeout (Numeric) (defaults to: 30)

    read timeout, seconds.

  • interpolate (Boolean) (defaults to: true)

    expand $OTHER_SECRET references in resolved values (default true); false returns the stored text verbatim.

Raises:



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/seekrit/client.rb', line 26

def initialize(token: nil, api_url: nil, with: {}, open_timeout: 10, read_timeout: 30,
               interpolate: true)
  @token = token || ENV["SEEKRIT_TOKEN"]
  raise Error, "no service token: pass token: or set SEEKRIT_TOKEN" unless @token && !@token.empty?

  @key = Crypto::TokenKey.parse(@token) # fail fast on a bad token
  @api_url = (api_url || ENV["SEEKRIT_API_URL"] || DEFAULT_API_URL).sub(%r{/+\z}, "")
  @with = with || {}
  @open_timeout = open_timeout
  @read_timeout = read_timeout
  @interpolate = interpolate
end

Instance Method Details

#get(name, default = nil) ⇒ Object

Resolve and return a single secret's value, or default if absent.



46
47
48
# File 'lib/seekrit/client.rb', line 46

def get(name, default = nil)
  resolve.fetch(name, default)
end

#into_env(env = ENV, override: false) ⇒ Object

Load resolved secrets into env (default ENV). Existing keys are kept unless override: is true. Returns the resolved secrets.



52
53
54
55
56
57
58
# File 'lib/seekrit/client.rb', line 52

def into_env(env = ENV, override: false)
  merged = resolve
  merged.each do |name, value|
    env[name] = value if override || !env.key?(name)
  end
  merged
end

#resolveHash{String=>String}

Fetch, decrypt, and merge; returns { "NAME" => value }. Fail-closed.

Returns:

  • (Hash{String=>String})


41
42
43
# File 'lib/seekrit/client.rb', line 41

def resolve
  Crypto.materialize(fetch, @key, interpolate: @interpolate)
end