add support for HashiCorp signed SSH certificates

This commit is contained in:
Ryan Petrello
2019-02-22 14:45:27 -05:00
committed by Jake McDermott
parent 4ed5bca5e3
commit 7a43f00a5d
7 changed files with 114 additions and 35 deletions

View File

@@ -37,7 +37,7 @@ azure_keyvault_inputs = {
}
def azure_keyvault_backend(**kwargs):
def azure_keyvault_backend(raw, **kwargs):
url = kwargs['url']
def auth_callback(server, resource, scope):

View File

@@ -6,22 +6,12 @@ from .plugin import CredentialPlugin
from hvac import Client
hashi_inputs = {
base_inputs = {
'fields': [{
'id': 'url',
'label': 'Server URL',
'type': 'string',
'help_text': 'The URL to the HashiCorp Vault',
}, {
'id': 'secret_path',
'label': 'Path to Secret',
'type': 'string',
'help_text': 'The path to the secret e.g., /some-engine/some-secret/',
}, {
'id': 'secret_field',
'label': 'Key Name',
'type': 'string',
'help_text': 'The name of the key to look up in the secret.',
}, {
'id': 'token',
'label': 'Token',
@@ -29,31 +19,60 @@ hashi_inputs = {
'secret': True,
'help_text': 'The access token used to authenticate to the Vault server',
}, {
'id': 'api_version',
'label': 'API Version',
'choices': ['v1', 'v2'],
'help_text': 'API v1 is for static key/value lookups. API v2 is for versioned key/value lookups.',
'default': 'v1',
'id': 'secret_path',
'label': 'Path to Secret',
'type': 'string',
'help_text': 'The path to the secret e.g., /some-engine/some-secret/',
}],
'required': ['url', 'token', 'secret_path'],
}
hashi_kv_inputs = {
'fields': base_inputs['fields'] + [{
'id': 'secret_field',
'label': 'Key Name',
'type': 'string',
'help_text': 'The name of the key to look up in the secret.',
}, {
'id': 'secret_version',
'label': 'Secret Version (v2 only)',
'type': 'string',
'help_text': 'Used to specify a specific secret version (if left empty, the latest version will be used).',
}, {
'id': 'api_version',
'label': 'API Version',
'choices': ['v1', 'v2'],
'help_text': 'API v1 is for static key/value lookups. API v2 is for versioned key/value lookups.',
'default': 'v1',
}],
'required': ['url', 'secret_path', 'secret_field', 'token', 'api_version'],
'required': base_inputs['required'] + ['secret_field', 'api_version']
}
hashi_ssh_inputs = {
'fields': base_inputs['fields'] + [{
'id': 'role',
'label': 'Role Name',
'type': 'string',
'help_text': 'The name of the role used to sign.'
}, {
'id': 'valid_principals',
'label': 'Valid Principals',
'type': 'string',
'help_text': 'Valid principals (either usernames or hostnames) that the certificate should be signed for.',
}],
'required': base_inputs['required'] + ['role']
}
def hashi_backend(**kwargs):
token = kwargs.get('token')
url = kwargs.get('url')
secret_path = kwargs.get('secret_path')
def kv_backend(raw, **kwargs):
token = kwargs['token']
url = kwargs['url']
secret_path = kwargs['secret_path']
secret_field = kwargs.get('secret_field', None)
verify = kwargs.get('verify', False)
api_version = kwargs.get('api_version', None)
client = Client(url=url, token=token, verify=verify)
client = Client(url=url, token=token, verify=True)
if api_version == 'v2':
try:
mount_point, *path = pathlib.Path(secret_path.lstrip(os.sep)).parts
@@ -90,8 +109,31 @@ def hashi_backend(**kwargs):
return response['data']
hashivault_plugin = CredentialPlugin(
def ssh_backend(raw, **kwargs):
token = kwargs['token']
url = kwargs['url']
client = Client(url=url, token=token, verify=True)
json = {
'public_key': raw
}
if kwargs.get('valid_principals'):
json['valid_principals'] = kwargs['valid_principals']
resp = client._adapter.post(
'/v1/{}/sign/{}'.format(kwargs['secret_path'], kwargs['role']),
json=json,
)
return resp.json()['data']['signed_key']
hashivault_kv_plugin = CredentialPlugin(
'HashiCorp Vault Secret Lookup',
inputs=hashi_inputs,
backend=hashi_backend
inputs=hashi_kv_inputs,
backend=kv_backend
)
hashivault_ssh_plugin = CredentialPlugin(
'HashiCorp Vault Signed SSH',
inputs=hashi_ssh_inputs,
backend=ssh_backend
)