diff --git a/lib/vault/api/auth.rb b/lib/vault/api/auth.rb index 7a0b0eea..161821e7 100644 --- a/lib/vault/api/auth.rb +++ b/lib/vault/api/auth.rb @@ -264,6 +264,41 @@ def gcp(role, jwt, path = 'gcp') return secret end + # Authenticate via the kubernetes authentication method. If authentication is + # successful, the resulting token will be stored on the client and used + # for future requests. + # + # @example + # Vault.auth.kubernetes("default", "/var/run/secrets/kubernetes.io/serviceaccount/token") + # #=> # + # + # @param [String] role + # @param [String] service_account_path optional + # Path on filesystem of service account token secret. + # @param [String] route optional + # + # @return [Secret] + def kubernetes(role, service_account_path = nil, route = nil) + route ||= '/v1/auth/kubernetes/login' + service_account_path ||= + '/var/run/secrets/kubernetes.io/serviceaccount/token' + + payload = { + role: role, + jwt: File.read(service_account_path) + } + + json = client.post( + route, + JSON.fast_generate(payload) + ) + + secret = Secret.decode(json) + client.token = secret.auth.client_token + + return secret + end + # Authenticate via a TLS authentication method. If authentication is # successful, the resulting token will be stored on the client and used # for future requests. diff --git a/spec/unit/auth_spec.rb b/spec/unit/auth_spec.rb index 74b0f63f..4323e6df 100644 --- a/spec/unit/auth_spec.rb +++ b/spec/unit/auth_spec.rb @@ -2,7 +2,22 @@ module Vault describe Authenticate do - let(:auth) { Authenticate.new(client: nil) } + let(:client) { double('client') } + let(:auth) { Authenticate.new(client: client) } + + describe '#kubernetes' do + before do + allow(::File).to receive(:read).with( + '/var/run/secrets/kubernetes.io/serviceaccount/token' + ).and_return('abc123') + end + + it 'authenticates with Kubernetes Auth method' do + expect(client).to receive(:post).with('/v1/auth/kubernetes/login', '{"blah": "wrong"}') + expect(auth.kubernetes('test-role')).to eq('secret') + end + end + describe "#region_from_sts_endpoint" do subject { auth.send(:region_from_sts_endpoint, sts_endpoint) }