def finish_secret(secretsmanager: Client, secret_id: str, token: str): """ Finish the process of rotating a secret. Make the pending secret version the new current secret. :param secretsmanager: boto3 client for working with SecretsManager. :param secret_id: ARN of the secret which is being rotated. :param token: Unique identifier which will be the version ID of the new current secret version. """ secret_metadata = secretsmanager.describe_secret(SecretId=secret_id) new_version = token current_version = None for version in secret_metadata["VersionIdsToStages"]: if "AWSCURRENT" in secret_metadata["VersionIdsToStages"][version]: if version == new_version: print( f"Version {version} already marked as AWSCURRENT for secret {secret_id}." ) return current_version = version break secretsmanager.update_secret_version_stage( SecretId=secret_id, VersionStage="AWSCURRENT", MoveToVersionId=new_version, RemoveFromVersionId=current_version) print( f"Successfully set AWSCURRENT stage to version {new_version} for secret {secret_id}." )
def create_secret(secretsmanager: Client, secret_id: str, token: str): """ Begin the process of rotating a secret by creating a new secret which will be in a pending stage. Check to see if a secret already exists with the given token. If it doesn't exist, create a new secret with the token. :param secretsmanager: boto3 client for working with SecretsManager. :param secret_id: ARN of the secret which will be rotated. :param token: Unique identifier which will be the version ID of the pending secret version. """ current_dict = get_secret_dict(secretsmanager, secret_id, "AWSCURRENT") try: # Check to see if there is already a pending secret. secretsmanager.get_secret_value(SecretId=secret_id, VersionId=token, VersionStage="AWSPENDING") print(f"Successfully retreived secret: {secret_id}.") except secretsmanager.exceptions.ResourceNotFoundException: # If there is not a pending secret, create one. print(f"Generating a key pair with token: {token}.") private_key, public_key = generate_key_pair(token) current_dict['PublicKey'] = public_key current_dict['PrivateKey'] = private_key secret_string = json.dumps(current_dict) secretsmanager.put_secret_value(SecretId=secret_id, ClientRequestToken=token, SecretString=secret_string, VersionStages=['AWSPENDING']) print( f"Successfully created pending secret with id: {secret_id}, and token: {token}." )
def get_google_account_password(secretsmanager: SecretsManagerClient) -> str: """ Get a Google account password from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The Google account password. """ secret = secretsmanager.get_secret_value(SecretId="google-account-secret") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["password"]
def get_jenkins_password(secretsmanager: SecretsManagerClient) -> str: """ Get the password for jenkins.jarombek.io from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The Jenkins password. """ secret = secretsmanager.get_secret_value(SecretId="jenkins-secret") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["password"]
def get_github_access_token(secretsmanager: SecretsManagerClient) -> str: """ Get an access token for my GitHub account from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The access token. """ secret = secretsmanager.get_secret_value(SecretId=f"github-access-token") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["access_token"]
def get_github_key(secretsmanager: SecretsManagerClient) -> str: """ Get my GitHub accounts private key from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The private key. """ secret = secretsmanager.get_secret_value(SecretId=f"github-secret") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["private_key"]
def get_saintsxctf_password(secretsmanager: SecretsManagerClient) -> str: """ Get the password for the SaintsXCTF user 'andy'. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The user's password. """ secret = secretsmanager.get_secret_value( SecretId="saints-xctf-andy-password") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["password"]
def get_docker_hub_credentials( secretsmanager: SecretsManagerClient) -> Tuple[str, str]: """ Get the username and password for DockerHub from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: A tuple containing the username and password. """ secret = secretsmanager.get_secret_value(SecretId="dockerhub-secret") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["username"], secret_dict["password"]
def get_secret_dict(secretsmanager: Client, secret_id: str, stage: str, token: Optional[str] = None) -> dict: """ Get the current secret value as a python dictionary. :param secretsmanager: boto3 client for working with SecretsManager. :param secret_id: ARN of the secret which will be rotated. :param stage: Stage of the secret (ex. "AWSCURRENT", "AWSPENDING"). :param token: Unique identifier which will be the version ID of the new secret version. :return: A python dictionary containing a PrivateKey and PublicKey. """ if token: secret = secretsmanager.get_secret_value(SecretId=secret_id, VersionId=token, VersionStage=stage) else: secret = secretsmanager.get_secret_value(SecretId=secret_id, VersionStage=stage) secret_string = secret['SecretString'] return json.loads(secret_string)
def get_rds_credentials(secretsmanager: SecretsManagerClient, env: str) -> dict: """ Get the RDS username and password. :param secretsmanager: boto3 client for working with SecretsManager. :param env: Environment of the SaintsXCTF database. :return: A dictionary containing username and password keys. """ print("Getting RDS Credentials") response = secretsmanager.get_secret_value( SecretId=f'saints-xctf-rds-{env}-secret') secret_string = response.get("SecretString") return json.loads(secret_string)
def get_aws_access_secrets( secretsmanager: SecretsManagerClient) -> Tuple[str, str]: """ Get secrets for AWS CLI and SDK access from AWS Secrets Manager. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: The AWS secrets. """ secret = secretsmanager.get_secret_value(SecretId=f"aws-access-secrets") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["aws_access_key_id"], secret_dict[ "aws_secret_access_key"]
def get_jwt_private_key(secretsmanager: SecretsManagerClient, env: str) -> str: """ Get the RSA encrypted private key used to create JWT tokens. :param secretsmanager: boto3 client for working with SecretsManager. :param env: Environment of the SaintsXCTF authentication private key. :return: A string representing the RSA encrypted private key. """ print("Getting JWT Private Key") secret = secretsmanager.get_secret_value( SecretId=f"saints-xctf-auth-{env}") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["PrivateKey"]
def get_saintsxctf_rds_credentials( env: str, secretsmanager: SecretsManagerClient) -> Tuple[str, str]: """ Get the username and password for an RDS database for SaintsXCTF. :param env: Environment of the database to get credentials for. Options: dev, prod. :param secretsmanager: Boto3 Secrets Manager client used to get secrets. :return: A tuple containing the username and password. """ secret = secretsmanager.get_secret_value( SecretId=f"saints-xctf-rds-{env}-secret") secret_string = secret.get('SecretString') secret_dict: dict = json.loads(secret_string) return secret_dict["username"], secret_dict["password"]