-
Notifications
You must be signed in to change notification settings - Fork 372
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'hvac:main' into sys/tools/random
- Loading branch information
Showing
11 changed files
with
753 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ Secrets Engines | |
database | ||
gcp | ||
identity | ||
ldap | ||
pki | ||
kv | ||
kv_v1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
LDAP | ||
================ | ||
|
||
.. contents:: | ||
|
||
Configure LDAP Secrets Secrets Engine | ||
------------------------------------- | ||
|
||
Configure the LDAP secrets engine to either manage service accounts or service account libraries. | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.configure` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
# Not all these settings may apply to your setup, refer to Vault | ||
# documentation for context of what to use here | ||
config_response = client.secrets.ldap.configure( | ||
binddn='username@domain.fqdn', # A upn or DN can be used for this value, Vault resolves the user to a dn silently | ||
bindpass='***********', | ||
url='ldaps://domain.fqdn', | ||
userdn='cn=Users,dn=domain,dn=fqdn', | ||
upndomain='domain.fqdn', | ||
userattr="cn", | ||
schema="openldap" | ||
) | ||
print(config_response) | ||
Read Config | ||
----------- | ||
|
||
Return the LDAP Secret Engine configuration. | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.read_config` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
config_response = client.secrets.ldap.read_config() | ||
Create or Update Static Role | ||
---------------------------- | ||
|
||
Create or Update a role which allows the retrieval and rotation of an LDAP account. Retrieve and rotate the actual credential via generate_static_credentials(). | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.create_or_update_static_role` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
role_response = client.secrets.ldap.create_or_update_static_role( | ||
name='hvac-role', | ||
username='sql-service-account', | ||
dn='cn=sql-service-account,dc=petshop,dc=com', | ||
rotation_period="60s") | ||
Read Static Role | ||
---------------- | ||
|
||
Retrieve the role configuration which allows the retrieval and rotation of an LDAP account. Retrieve and rotate the actual credential via generate_static_credentials(). | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.read_static_role` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
role_response = client.secrets.ldap.read_static_role(name='sql-service-account') | ||
List Static Roles | ||
----------------- | ||
|
||
List all configured roles which allows the retrieval and rotation of an LDAP account. Retrieve and rotate the actual credential via generate_static_credentials(). | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.list_static_roles` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
all_static_roles = client.secrets.ldap.list_static_roles() | ||
Delete Static Role | ||
------------------ | ||
|
||
Remove the role configuration which allows the retrieval and rotation of an LDAP account. | ||
|
||
Passwords are not rotated upon deletion of a static role. The password should be manually rotated prior to deleting the role or revoking access to the static role. | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.delete_static_role` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
deletion_response = client.secrets.ldap.delete_static_role(name='sql-service-account') | ||
Generate Static Credentials | ||
--------------------------- | ||
|
||
Retrieve a service account password from LDAP. Return the previous password (if known). Vault shall rotate | ||
the password before returning it, if it has breached its configured ttl. | ||
|
||
Source reference: :py:meth:`hvac.api.secrets_engines.ldap.generate_static_credentials` | ||
|
||
.. code:: python | ||
import hvac | ||
client = hvac.Client() | ||
# Authenticate to Vault using client.auth.x | ||
gen_creds_response = client.secrets.ldap.generate_static_credentials( | ||
name='hvac-role', | ||
) | ||
print('Retrieved Service Account Password: {access} (Current) / {secret} (Old)'.format( | ||
access=gen_creds_response['data']['current_password'], | ||
secret=gen_creds_response['data']['old_password'], | ||
)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
#!/usr/bin/env python | ||
"""LDAP methods module.""" | ||
|
||
from hvac import utils | ||
from hvac.api.vault_api_base import VaultApiBase | ||
|
||
DEFAULT_MOUNT_POINT = "ldap" | ||
|
||
|
||
class Ldap(VaultApiBase): | ||
"""LDAP Secrets Engine (API). | ||
Reference: https://www.vaultproject.io/api/secret/ldap/index.html | ||
""" | ||
|
||
def configure( | ||
self, | ||
binddn=None, | ||
bindpass=None, | ||
url=None, | ||
password_policy=None, | ||
schema=None, | ||
userdn=None, | ||
userattr=None, | ||
upndomain=None, | ||
mount_point=DEFAULT_MOUNT_POINT, | ||
): | ||
"""Configure shared information for the ldap secrets engine. | ||
Supported methods: | ||
POST: /{mount_point}/config. Produces: 204 (empty body) | ||
:param binddn: Distinguished name of object to bind when performing user and group search. | ||
:type binddn: str | unicode | ||
:param bindpass: Password to use along with binddn when performing user search. | ||
:type bindpass: str | unicode | ||
:param url: Base DN under which to perform user search. | ||
:type url: str | unicode | ||
:param userdn: Base DN under which to perform user search. | ||
:type userdn: str | unicode | ||
:param upndomain: userPrincipalDomain used to construct the UPN string for the authenticating user. | ||
:type upndomain: str | unicode | ||
:param password_policy: The name of the password policy to use to generate passwords. | ||
:type password_policy: str | unicode | ||
:param schema: The LDAP schema to use when storing entry passwords. Valid schemas include ``openldap``, ``ad``, and ``racf``. | ||
:type schema: str | unicode | ||
:param mount_point: The "path" the method/backend was mounted on. | ||
:type mount_point: str | unicode | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
params = utils.remove_nones( | ||
{ | ||
"binddn": binddn, | ||
"bindpass": bindpass, | ||
"url": url, | ||
"userdn": userdn, | ||
"userattr": userattr, | ||
"upndomain": upndomain, | ||
"password_policy": password_policy, | ||
"schema": schema, | ||
} | ||
) | ||
|
||
api_path = utils.format_url("/v1/{mount_point}/config", mount_point=mount_point) | ||
return self._adapter.post( | ||
url=api_path, | ||
json=params, | ||
) | ||
|
||
def read_config(self, mount_point=DEFAULT_MOUNT_POINT): | ||
"""Read the configured shared information for the ldap secrets engine. | ||
Credentials will be omitted from returned data. | ||
Supported methods: | ||
GET: /{mount_point}/config. Produces: 200 application/json | ||
:param mount_point: The "path" the method/backend was mounted on. | ||
:type mount_point: str | unicode | ||
:return: The JSON response of the request. | ||
:rtype: dict | ||
""" | ||
api_path = utils.format_url("/v1/{mount_point}/config", mount_point=mount_point) | ||
return self._adapter.get( | ||
url=api_path, | ||
) | ||
|
||
def rotate_root(self, mount_point=DEFAULT_MOUNT_POINT): | ||
"""Rotate the root password for the binddn entry used to manage the ldap secrets engine. | ||
Supported methods: | ||
POST: /{mount_point}/rotate root. Produces: 200 application/json | ||
:param mount_point: The "path" the method/backend was mounted on. | ||
:type mount_point: str | unicode | ||
:return: The JSON response of the request. | ||
:rtype: dict | ||
""" | ||
api_path = utils.format_url( | ||
"/v1/{mount_point}/rotate-root", mount_point=mount_point | ||
) | ||
return self._adapter.post(url=api_path) | ||
|
||
def create_or_update_static_role( | ||
self, | ||
name, | ||
username=None, | ||
dn=None, | ||
rotation_period=None, | ||
mount_point=DEFAULT_MOUNT_POINT, | ||
): | ||
"""This endpoint creates or updates the ldap static role definition. | ||
:param name: Specifies the name of an existing static role against which to create this ldap credential. | ||
:type name: str | unicode | ||
:param username: The name of a pre-existing service account in LDAP that maps to this static role. | ||
This value is required on create and cannot be updated. | ||
:type username: str | unicode | ||
:param dn: Distinguished name of the existing LDAP entry to manage password rotation for (takes precedence over username). | ||
Optional but cannot be modified after creation. | ||
:type dn: str | unicode | ||
:param rotation_period: How often Vault should rotate the password. | ||
This is provided as a string duration with a time suffix like "30s" or "1h" or as seconds. | ||
If not provided, the default Vault rotation_period is used. | ||
:type rotation_period: str | unicode | ||
:param mount_point: Specifies the place where the secrets engine will be accessible (default: ad). | ||
:type mount_point: str | unicode | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
api_path = utils.format_url("/v1/{}/static-role/{}", mount_point, name) | ||
params = {"username": username, "rotation_period": rotation_period} | ||
params.update(utils.remove_nones({"dn": dn})) | ||
return self._adapter.post( | ||
url=api_path, | ||
json=params, | ||
) | ||
|
||
def read_static_role(self, name, mount_point=DEFAULT_MOUNT_POINT): | ||
"""This endpoint queries for information about an ldap static role with the given name. | ||
If no role exists with that name, a 404 is returned. | ||
:param name: Specifies the name of the static role to query. | ||
:type name: str | unicode | ||
:param mount_point: Specifies the place where the secrets engine will be accessible (default: ad). | ||
:type mount_point: str | unicode | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
api_path = utils.format_url("/v1/{}/static-role/{}", mount_point, name) | ||
return self._adapter.get( | ||
url=api_path, | ||
) | ||
|
||
def list_static_roles(self, mount_point=DEFAULT_MOUNT_POINT): | ||
"""This endpoint lists all existing static roles in the secrets engine. | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
api_path = utils.format_url("/v1/{}/static-role", mount_point) | ||
return self._adapter.list( | ||
url=api_path, | ||
) | ||
|
||
def delete_static_role(self, name, mount_point=DEFAULT_MOUNT_POINT): | ||
"""This endpoint deletes an ldap static role with the given name. | ||
Even if the role does not exist, this endpoint will still return a successful response. | ||
:param name: Specifies the name of the role to delete. | ||
:type name: str | unicode | ||
:param mount_point: Specifies the place where the secrets engine will be accessible (default: ad). | ||
:type mount_point: str | unicode | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
api_path = utils.format_url("/v1/{}/static-role/{}", mount_point, name) | ||
return self._adapter.delete( | ||
url=api_path, | ||
) | ||
|
||
def generate_static_credentials(self, name, mount_point=DEFAULT_MOUNT_POINT): | ||
"""This endpoint retrieves the previous and current LDAP password for | ||
the associated account (or rotate if required) | ||
:param name: Specifies the name of the static role to request credentials from. | ||
:type name: str | unicode | ||
:param mount_point: Specifies the place where the secrets engine will be accessible (default: ad). | ||
:type mount_point: str | unicode | ||
:return: The response of the request. | ||
:rtype: requests.Response | ||
""" | ||
api_path = utils.format_url("/v1/{}/static-cred/{}", mount_point, name) | ||
return self._adapter.get( | ||
url=api_path, | ||
) |
Oops, something went wrong.