Skip to content

Commit

Permalink
Token swap (#43)
Browse files Browse the repository at this point in the history
* use a bootstrap token, then switch
  • Loading branch information
suprjinx authored Oct 3, 2024
1 parent 7146eab commit 3598418
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 18 deletions.
13 changes: 6 additions & 7 deletions app/lib/clients/vault.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
module Clients
class Vault
class_attribute :token

class << self
private

def client
::Vault::Client.new(
address: vault_address,
token: vault_token
address: address,
token: token
)
end

def vault_address
def address
Config[:vault_addr]
end

def vault_token
Config[:vault_token]
end

def enable_engine(mount, type)
client.sys.mount(mount, type, "#{type} secrets engine")
end
Expand All @@ -26,6 +24,7 @@ def enable_engine(mount, type)

require_relative "vault/key_value"
require_relative "vault/certificate"
require_relative "vault/policy"
require_relative "vault/entity"
require_relative "vault/entity_alias"
end
8 changes: 4 additions & 4 deletions app/lib/clients/vault/certificate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def configure_root_ca
File.write("tmp/#{root_ca_mount}.crt", root_cert)

client.logical.write("#{root_ca_mount}/config/cluster",
path: "#{vault_address}/v1/#{root_ca_mount}",
aia_path: "#{vault_address}/v1/#{root_ca_mount}")
path: "#{address}/v1/#{root_ca_mount}",
aia_path: "#{address}/v1/#{root_ca_mount}")

client.logical.write("#{root_ca_mount}/config/urls",
issuing_certificates: "{{cluster_aia_path}}/issuer/{{issuer_id}}/der",
Expand Down Expand Up @@ -100,8 +100,8 @@ def sign_cert
def configure_ca
# Configure the intermediate CA
client.logical.write("#{intermediate_ca_mount}/config/cluster",
path: "#{vault_address}/v1/#{intermediate_ca_mount}",
aia_path: "#{vault_address}/v1/#{intermediate_ca_mount}")
path: "#{address}/v1/#{intermediate_ca_mount}",
aia_path: "#{address}/v1/#{intermediate_ca_mount}")

# Configure the role for issuing certs
issuer_ref = client.logical.read("#{intermediate_ca_mount}/config/issuers").data[:default]
Expand Down
1 change: 0 additions & 1 deletion app/lib/clients/vault/key_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ def kv_read(path)
end

def kv_write(path, data)
configure_kv
client.logical.write("#{kv_mount}/data/#{path}", data: data)
end

Expand Down
37 changes: 37 additions & 0 deletions app/lib/clients/vault/policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module Clients
class Vault
class << self
def rotate_token
create_astral_policy
token = create_astral_token
Clients::Vault.token = token
end

private

def create_astral_policy
policy = <<-HCL
path "#{intermediate_ca_mount}/roles/astral" {
capabilities = ["read", "list"]
}
path "#{intermediate_ca_mount}/issue/astral" {
capabilities = ["create", "update"]
}
path "#{kv_mount}/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
HCL

client.sys.put_policy("astral_policy", policy)
end

def create_astral_token
token = client.auth_token.create(
policies: [ "astral_policy" ],
ttl: "24h"
)
token.auth.client_token
end
end
end
end
3 changes: 3 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ class Application < Rails::Application
config.astral = config_for :astral

config.after_initialize do
# bootstrap with provided token, then rotate
Clients::Vault.token = Config[:vault_token]
Clients::Vault.configure_kv
Clients::Vault.configure_pki
Clients::Vault.rotate_token
end
end
end
32 changes: 26 additions & 6 deletions test/lib/clients/vault_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,38 @@
class VaultTest < ActiveSupport::TestCase
attr_reader :intermediate_ca_mount
attr_reader :root_ca_mount
attr_reader :kv_mount
attr_reader :policies
attr_reader :entity_name
attr_reader :alias_name

setup do
@client = Clients::Vault
@token = Clients::Vault.token
Clients::Vault.token = vault_token
@root_ca_mount = SecureRandom.hex(4)
@intermediate_ca_mount = SecureRandom.hex(4)
@kv_mount = SecureRandom.hex(4)
@policies = SecureRandom.hex(4)
@entity_name = SecureRandom.hex(4)
@alias_name = SecureRandom.hex(4)
end
end

teardown do
Clients::Vault.token = @token
vault_client.sys.unmount(root_ca_mount)
vault_client.sys.unmount(intermediate_ca_mount)
end

test "#configure_kv" do
@client.stub :kv_mount, intermediate_ca_mount do
test ".configure_kv" do
@client.stub :kv_mount, kv_mount do
assert @client.configure_kv
engines = vault_client.sys.mounts
assert_equal "kv", engines[intermediate_ca_mount.to_sym].type
assert_equal "kv", engines[kv_mount.to_sym].type
end
end

test "#configure_pki" do
test ".configure_pki" do
@client.stub :root_ca_mount, root_ca_mount do
@client.stub :intermediate_ca_mount, intermediate_ca_mount do
assert @client.configure_pki
Expand All @@ -53,6 +59,16 @@ class VaultTest < ActiveSupport::TestCase
end
end

test ".rotate_token" do
# begins with default token
assert_equal vault_token, @client.token
assert @client.rotate_token
# now has a new token
assert_not_equal vault_token, @client.token
# ensure we can write with the new token
assert_instance_of Vault::Secret, @client.kv_write("testing/secret", { password: "sicr3t" })
end

test "#entity" do
entity = @client.read_entity(@entity_name)
assert_nil entity
Expand Down Expand Up @@ -99,11 +115,15 @@ class VaultTest < ActiveSupport::TestCase
def vault_client
::Vault::Client.new(
address: vault_addr,
token: Config[:vault_token]
token: vault_token
)
end

def vault_addr
Config[:vault_addr]
end

def vault_token
Config[:vault_token]
end
end

0 comments on commit 3598418

Please sign in to comment.