All pages
Powered by GitBook
1 of 38

Integrations

CI/CD Integrations provided with Keeper Secrets Manager

Keeper Secrets Manager integrates into popular CI/CD platforms and development environments. Use Keeper Secrets Manager to inject secrets into your build processes, and remove hard-coded credentials from your environments.

Ansible

A collection of Ansible plugins that interact with Keeper Secrets Manager

Go to Ansible Documentation

AWS CLI Credential Process

Protect your AWS Access Keys with Keeper Secrets Manager

Go to AWS CLI Credential Process Documentation

AWS Secrets Manager

Sync secrets from the Keeper Vault with AWS Secrets Manager

Go to AWS Secrets Manager Documentation

AWS KMS Encryption

Protect your Keeper Secrets Manager configuration with AWS KMS.

Go to AWS KMS Documentation

Azure DevOps

Securely retrieve secrets from the Keeper Vault and use them in Azure DevOps pipelines. Remove hardcoded values, fetch secure files, and keep all your build credentials in the Keeper Vault.

Go to Azure DevOps Integration

Azure Key Vault Sync

Sync secrets from the Keeper Vault with Azure Key Vault.

Go to Azure Key Vault Sync Documentation

Azure Key Vault Encryption

Protect your Keeper Secrets Manager configuration with Azure Key Vault.

Go to Azure Key Vault Encryption Documentation

BitBucket

Retrieve secrets from the Keeper Vault within BitBucket Pipelines.

Go to BitBucket Plugin Documentation

Docker Image

The Secrets Manager CLI can be used to pull secrets from a Docker image at runtime, or it can be used by building it into the docker image.

Go to Docker Image Documentation

Docker Runtime

Keeper Secrets Manager integrates with the Docker Runtime so that you can dynamically retrieve a secret from the vault when the container executes.

Go to Docker Runtime Documentation

Docker Writer Image

A general purpose docker image to retrieve secrets.

Go to Docker Write Image

Entrust HSM Encryption

Protect your Keeper Secrets Manager connections with the Entrust HSM

Go to Entrust HSM Documentation

Git - Sign Commits with SSH Key

This integration will let you sign git commits with an SSH key in your Keeper Vault (via Keeper Secrets Manager) rather than using a key stored on disk.

Go to Git Integrations

GitHub Actions

This action securely retrieves secrets from Keeper and places them to the desired destination of the GitHub Actions runner such as an environment variable, output parameters of the step or to a file.

Go to Github Actions Integration

GitLab

Bring secret credentials into your GitLab Pipeline builds using Keeper's Secrets Manager GitLab plugin.

Go to GitLab Documentation

Google Cloud Secret Manager Sync

Sync secrets from the Keeper Vault with GCP Secret Manager.

Go to GCP Secret Manager Documentation

Google Cloud Key Management Encryption

Protect your Keeper Secrets Manager connections with GCP Key Management.

Go to GCP Key Management Encryption Documentation

Hashicorp Vault

Use Keeper Secrets Manager with HashiCorp Vault as a Data Source

Go to Hashicorp Vault Documentation

Heroku

Use Keeper Secrets Manager SDKs to bring secret credentials and files securely into Heroku builds.

Go to Heroku Documentation

Jenkins Plugin

The Jenkins plugin for Keeper Secrets Manager allows you retrieve secrets from the Keeper Vault and place the values into environmental variables or files within the builder and workflow pipelines.

Go to Jenkins Plugin Documentation

Keeper Connection Manager

Store connection credentials in the Keeper Vault and easily use them in Connection Manager.

Go to Keeper Connection Manager Documentation

Kubernetes

Keeper Secrets Manager can be integrated into your K8s cluster for accessing Keeper secrets in real-time across all pods.

Go to the Kubernetes External Secrets Operator Documentation

Go to the legacy Kubernetes Documentation

Linux Keyring

Store and retrieve secrets from the Linux Keyring

Go to the Linux Keyring Documentation

Model Context Protocol (MCP) for AI Agents (Docker)

Integrate Keeper Secrets Manager into AI agents using this Docker container

Go to the MCP Documentation for Docker

Model Context Protocol (MCP) for AI Agents (Node)

Integrate Keeper Secrets Manager into AI agents using this Node module

Go to the MCP Documentation for Node

Octopus Deploy

Use credentials from your Keeper Vault in Octopus Deploy workflows. Integrate with Keeper Secrets Manager to securely access all the platforms and services you connect to with Octopus Deploy.

Go to Octopus Documentation

Oracle Key Vault Encryption

Protect your Keeper Secrets Manager connections with Oracle Key Vault.

Go to Oracle Key Vault Encryption Documentation

PowerShell

Utilize PowerShell's Secret Management module to access secrets from Keeper.

Go to PowerShell Documentation

ServiceNow

Retrieve credentials from the vault from the ServiceNow Management, Instrumentation, and Discovery (MID) Server integration.

Go to ServiceNow Documentation

TeamCity

Use secrets from the Keeper vault in TeamCity builds.

Go to TeamCity Documentation

Teller

Retrieve secrets from the Keeper Vault within Teller environments.

Go to Teller Documentation

Terraform

The Keeper Terraform Plugin utilizes Keeper Secrets Manager to provide access to secret credentials saved in the Keeper Vault. The Keeper Terraform plugin allows for injecting secrets directly into Terraform builds securely using Keeper's zero-knowledge infrastructure.

Go to Terraform Documentation

Windows Credential Manager

Store and retrieve secrets from the Windows Credential Manager

Go to the Windows Credential Manager Documentation

XSOAR

Use credentials from your Keeper Vault in XSOAR workflows. Integrate with Keeper Secrets Manager to securely access all the platforms and services you connect to with XSOAR.

Go to XSOAR Documentation

CLI Tools

Use Keeper Secrets Manager in a CLI environment. Build scripts that securely utilize your secrets, or easily access Secrets Manager functionality from your terminal.

PowerShell

The Keeper Secrets Manager PowerShell plugin utilizes Microsoft PowerShell's Secret Management module to inject secrets from the Keeper Vault into your PowerShell scripts.

Go to PowerShell Documentation

Secrets Manager CLI

The Keeper Secrets Manager CLI ("KSM CLI") provides core Secrets Manager Vault interaction from a terminal, shell script or any software that can be launched from a shell.

Go to Secrets Manager CLI

Ansible

Use Keeper Secrets Manager with Ansible

Features

  • Retrieve secrets from the Keeper vault to use in Ansible Playbooks

  • Update the value of secrets in the Keeper Vault from Ansible

  • Copy files from the Keeper Vault

  • Use Keeper Secrets Manager within Ansible Tower to fetch secret credentials and files in your Ansible Playbooks.

For a complete list of Keeper Secrets Manager features see the Overview

Ansible Integrations

Check out the nested pages for using Secrets Manager with Ansible

Ansible Plugin

How to use Keeper Secrets Manager to fetch secret credentials and files in your Ansible Playbooks

Ansible Tower

Store Keeper Secrets Manager configuration credentials in Ansible Tower and create reusable playbook templates that utilize Keeper Secrets Manager features.

Ansible Plugin

A collection of Ansible plugins that interact with your Keeper account and can be used in your automations.

Features

  • Retrieve secrets from the Keeper vault to use in Ansible Playbooks

  • Update the value of secrets in the Keeper Vault from Ansible

  • Create records from Ansible

  • Copy files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Ansible integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Ansible integration accepts both Base64 and JSON format configurations

Installation

Due to the flexibility of Ansible, where you install the plugins depends on your Ansible installation and playbook locations.

Install Keeper Ansible Module

Installation via Ansible Galaxy

The collection can be found on the Ansible Galaxy website. You can install the collection with the follow command line.

$ ansible-galaxy collection install keepersecurity.keeper_secrets_manager

Ansible Galaxy collection uses long plugin names. The name is the collection name combined with the plugin name. For example, the keeper_copy plugin name when using Ansible Galaxy is keeper_security.keeper_secrets_manager.keeper_copy. If you want to use the short plugin name, add keepersecurity.keeper_secrets_manager to the collections block of your playbook.

- name: Keeper Copy
  hosts: my_hosts
  collections: 
    - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Copy a password
      keeper_copy:
        uid: RECORD UID
        ...

Installing via Ansible Galaxy assumes you already have Ansible installed. Ansible Galaxy cannot install dependencies. The following dependencies will need to be installed manually, via pip, into your the python library or virtualenv used by Ansible.

  • importlib_metadata

  • keeper-secrets-manager-core>=16.4.1

  • keeper-secrets-manager-helper>=1.0.4

Installation via Pypi

The Ansible module for Keeper is installed with the command below. Make note of the location where the module is installed, as this will be needed in the Ansible playbook configuration.

$ pip3 install -U keeper_secrets_manager_ansible

Find the Keeper Secrets Manager Ansible Plugin source code in the GitHub repository.

The Keeper ansible plugins are installed in the site-packages directory of your version of Python or your current virtual environment. You can find the plugin locations using the following command:

$ keeper_ansible --config

# Below are the directory paths to action and lookup plugins.
ANSIBLE_ACTION_PLUGINS=...site-packages/keeper_secrets_manager_ansible/plugins/action_plugins
ANSIBLE_LOOKUP_PLUGINS=...site-packages/keeper_secrets_manager_ansible/plugins/lookup_plugins

Those paths can be used in your ansible.cfg.

[defaults]
action_plugins = ...site-packages/keeper_secrets_manager_ansible/plugins/action_plugins
lookup_plugins = ...site-packages/keeper_secrets_manager_ansible/plugins/lookup_plugins

Generate a Config File

Prior to proceeding with this guide, make sure you meet all the prerequisites and have the following:

  • KSM Application and it's One-Time Access Token

  • Keeper Ansible module installed

In order to use the Ansible plugin for Keeper Secrets Manager, a Keeper config file is required. Once you have a config file, the configuration values can be placed into the Ansible variable files. These variable files can be encrypted with Ansible vault.

Using the Keeper Ansible module and the generated One-Time Access Token, generate a Configuration file:

$ keeper_ansible --token XX:XXXXXX
Config file create at location client-config.json

This will generate the Keeper JSON configuration file in the current directory.

If you do not have your Python module bin path added your PATH environment variable, you can create a config with the following command.

$ python3 -m keeper_secrets_manager_ansible --token XX:XXXXXX
Config file create at location client-config.json

The default name for the JSON configuration file is client-config.json. The content of the file will look like the following:

{
    "appKey" : "XXXXXXXX",
    "appOwnerPublicKey": "XXXXXXX",
    "clientId": "XXXXXXXX",
    "hostname": "XXXXX",
    "privateKey": "XXXXXXXX",
    "serverPublicKeyId": "XX"
}

This config file allows your Ansible playbook to authenticate and retrieve designated secrets from the vault.

Ansible Variables

The Keeper Secrets Manager plugins can use multiple configuration methods. For example, the Base64 encode configuration can be used.

---
keeper_config: U09NRVRFc2R ... GFzZGFzZGFzZHNhWFQK==

Ansible can use the client-config.json config file directly. It can be specified in the Ansible variables using the keeper_config_file variable key.

---
keeper_config_file: /path/to/client-config.json

Another solution is to place the values in your client-config.json file into an Ansible variable file. For example, the values can be placed into the group_vars, host_vars, or in the task files:

---
keeper_app_key: XXXXX
keeper_client_id: XXXXX
keeper_token: XXXXX
keeper_private_key: XXXXX
keeper_app_owner_public_key: XXXXX
keeper_server_public_key_id: XX

For security, the group_vars or host_vars files can be encrypted with ansible-vault.

A list of valid Ansible Variables for the Keeper plugin are below:

Ansible Variable

JSON Key

Description

keeper_config

--

A Base64 encoded configuration string.

keeper_config_file

--

An alternative path and name for the JSON configuration file, if not current directory or named differently than client-config.json.

keeper_token

clientKey

The one time access token, also known as the client key. Only used to initialize the configuration.

keeper_client_id

clientId

The client id provided from Secrets Manager after the one time access token is used. Required.

keeper_app_key

appKey

The app key provided from the secret management service after the one time access token is used. Required.

keeper_private_key

privateKey

The private key provided from the secret management service after the one time access token is used. Required.

keeper_app_owner_public_key

appOwnerPublicKey

The public key used for creating records. Required if using the keeper_create plugin.

keeper_server_public_key_id

serverPublicKeyId

Selects which public key to use when connecting to the server. If the server wants a different public key the SDK will handle switching. Not required, but will reduce number of web service calls.

keeper_hostname

hostname

The Secrets Manager backend hostname. Defaults to US. Supports "US", "EU", "AU" and "US_GOV" values depending on your Keeper data center location. Required.

keeper_log_level

--

Set the log level of the SDK. Acceptable levels are DEBUG, INFO, WARNING, ERROR, and CRITICAL. Defaults to ERROR.

keeper_record_cache_secret

--

Required for the keeper_cache_records action. Used to encrypt records in cache. The value of this variable can be created in the playbook. See action example.

keeper_use_cache

--

Use a cache of the vault. Defaults to False. Cache file are only used as backup for network problems.

keeper_cache_dir

--

The directory to write and read the cache file.

keeper_record_types

--

An list of Keeper Commander record type definitions.

There are two caching methods in the plugin. They are not the same. keeper_record_cache_secret is used to cache records for a playbook run. After the playbook run, the cache is removed. The cache is stored in memory encrypted. This cache can be used to reduce the number of API called to the Keeper Secret Manager service. Since this cache is stored in memory, the more records retrieved the more memory is used. keeper_use_cache and keeper_cache_dir are used for Disaster Recovery caching of the Keeper Vault. This cached is used when connection to the Keeper Secret Manager service cannot be reached. This cache is stored encrypted on disk.

Command Line Variables

As an optional method, values can be passed in through the ansible-playbook command. Example:

$ ansible-playbook my_playbook.yml \
    -e "keeper_app_key=XXXXX" \
    -e "keeper_client_id=XXXXX" \
    -e "keeper_token=XXXXX" \
    -e "keeper_private_key=XXXXX"

Ansible Plugin Usage

There are three Keeper action plugins and one lookup plugin.

For all the plugins, the following arguments are used. Either the uid or title is required.

  • uid - The Record UID of the desired record.

  • title - The Record Title of the desired record.

  • field - Retrieve the value with specified label from the record.

  • custom_field - Retrieve the value with the specific custom field name.

  • file - Retrieve the file with the specified name from the record.

The uid value is required, and you need either field or file populated.

To find out what fields and custom fields are available for a specific vault secret, use the Keeper Secrets Manager CLI "ksm secret get -u XXXX" command. More info here.

The plugin example are shown with the short plugin names. If you installed the collection via Ansible Galaxy, you will need to use the longer plugin name or add the collection name to the list of collections used in your playbook.

Actions can either use Keeper Notation or the record UID or Title, combined with the task attributes array_index and value_key to get a specific value.

For example, a complex value like Phone number is an array of objects.

[
    {
        'number': '(555) 123-1234', 
        'type': 'Work', 
        'ext': '11'
    }, 
    {
        'region': 'AD', 
        'number': '111-2223333', 
        'ext': '5555', 
        'type': 'Mobile'
    }
]

The example, below is show how to use Keeper Notation and array_index and value_key to get the same result.

---
- name: Keeper Get
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Get the second phone number using Keeper Notation
      keeper_get:
        notation: "RECORD UID/field/phone[1][number]"
      register: second_number_notation
      
    - name: Get the second phone number using array_index and value_key
      keeper_get:
        uid: "RECORD UID"
        field: phone
        array_index: 1
        value_key: "number"
      register: second_number_non_notation

Plugin: keeper_cache_records

The plugin keeper_cache_records is used to retrieve a select amount of records to be stored in a cache. The cache can then be used by other actions. This is used to reduce the number of API calls by getting all required record up front.

---
- name: Cache records
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Generate a Keeper Record Cache secret
      keeper_password:
        length: 64
      register: keeper_record_cache_secret
      no_log: True

    - name: Store the Keeper Record Cache secret into variables.
      set_fact:
        keeper_record_cache_secret: "{{ keeper_record_cache_secret.password }}"
      no_log: True
      
    - name: Cache records. Will use keeper_record_cache_secret from above.
      keeper_cache_records:
        uids:
          - RECORD UID
          - RECORD UID
        titles:
          - My Record Title
          - My Record Title Too
      register: my_records
      no_log: True
        
    - name: Copy a file
      keeper_copy:
        cache: "{{ my_records.cache }}"
        uid: RECORD UID
        file: my_cert_file.crt
        dest: /etc/special.crt
        owner: root
        group: root
        mode: "0644"
        backup: yes

The records can be retrieved by the record UID or by the record title. The result of the action is an encrypted serialization of the records. The result should be stored in Ansible by using the register variable so it can be used by other actions. The encrypted serialization of the records can be quite long. For security and reducing log noise, it is recommended to set no_log to True.

keeper_cache_records caches records only. It does not cache attached files. If an action attempts to retrieve an attached file from a record that came from the cache, an API call will be made to download the file.

Use templating to set the attributes in other actions. For example cache: "{{ my_records.cache }}"

keeper_cache_records requires the keeper_record_cache_secret to be set. This can be done in the host, group, task variables, or generated in a task and then set as a fact (variable). In the example above, the keeper_password action is used to generate a password which is then stored as keeper_record_cache_secret. The no_log attribute is set to True to prevent the secret from being logged.

The cache will not update. The cache will not contain records created or updated after it has been generated. To get new records or changes in the cache, keeper_cache_records will need to be called again.

Required Attributes

  • uids - A list of Keeper Vault record UID.

  • titles - A list of titles of Keeper Vault records.

The attributes uids and titles can be used at the same time. At least one of them needs to be set.

Plugin: keeper_copy

The plugin keeper_copy is an extension of the built-in copy plugin. Example:

---
- name: Keeper Copy
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Copy a password.
      keeper_copy:
        uid: RECORD UID
        field: password
        dest: /tmp/my_password
        mode: "0600"

    - name: Copy a file
      keeper_copy:
        uid: RECORD UID
        file: my_cert_file.crt
        dest: /etc/special.crt
        owner: root
        group: root
        mode: "0644"
        backup: yes

In the examples, a password will be copied from the Keeper vault record and stored in the file /tmp/my_password on the remote system. It will use the Ansbile built-in copy plugin's mode attributes to changed the permissions of the file.

The last task example from above, the file "my_cert_file.crt" will be coped from the Keeper vault record and stored at the location "/tmp/special.crt". Several of the built-in copy plugin functions will be applied to the file.

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

  • notation - Use Keeper Notation to get the field from a record.

The attributes uids and titles can be used at the same time. At least one of them needs to be set.

Optional Attributes

  • cache - The record cache from the keeper_cache_records action.

  • field - Get the content from the standard Keeper Vault record.

  • custom_field - Get the content from the custom Keeper Vault record.

  • file - Get the content from the files attach to the Keeper Vault record by file title.

  • array_index - Defaults to 0. If the field value contains multiple values, this attribute will allow you to select which item to return. The first item will have the array_index of 0, and the next will be 1, etc.

  • value_key - If the field value is a complex object, this will allow you to select the key of the key/value pair to return.

Additional optional attributes are the same as the built-in copy plugin attributes. The attributes src, remote_src, and content are not allowed and will be ignored.

Plugin: keeper_get

The plugin keeper_get will retrieve a field or file from a Keeper vault record. Example:

---
- name: Keeper Get
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Get login name. Loading record from Keeper Vault.
      keeper_get:
        uid: RECORD UID
        field: login
      register: my_login
      
    - name: Print login name
      debug:
        var: my_login.value
        verbosity: 0
        
    - name: Make a sudoer
      copy:
        dest: "/etc/sudoers.d/{{ my_login.value }}"
        content: |
          # Auto added by Ansible
          {{ my_login.value }} ALL=(ALL:ALL) ALL

The keeper_get plugin returns a dictionary. The key "value" in the dictionary will contain the desired field or file content. This plugin is normally paired with the Ansible register instruction and the returned value is stored in memory so it can be accessed by other tasks.

In the example above, a record containing user's login name is retrieved. The login name is then stored under the name my_login. The second task will print the login name to your console for debug purposes. The third task will add a sudoer file for the login name with ability to execute all applications.

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

  • notation - Use Keeper Notation to get the field from a record.

The attributes uids and titles can be used at the same time. At least one of them needs to be set.

Optional Attributes

  • cache - The record cache from the keeper_cache_records action.

  • field - Get the value from the standard Keeper Vault record.

  • custom_field - Get the value from the custom Keeper Vault record.

  • file - Get the value from the files attach to the Keeper Vault record by file title.

  • allow_array - By default is False. If set to True, an array of values will be returned. This is needed if the field contains multiple values such as Phone numbers. If True, array_index and value_key will be ignored.

  • array_index - Defaults to 0. If the field value contains multiple values, this attribute will allow you to select which item to return. The first item will have the array_index of 0, and the next will be 1, etc.

  • value_key - If the field value is a complex object, this will allow you to select the key of the key/value pair to return.

Plugin: keeper_get_record

The plugin keeper_get_record will retrieve all the fields in the record and return them in a dictionary. Example:

---
- name: Keeper Get Record
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Get a record from the vault.
      keeper_get_record:
        uid: RECORD UID
        allow:
          - login
          - password
      register: my_record
      
    - name: Print login name
      debug:
        var: my_record.record.login[0]
        verbosity: 0

The keeper_get_record plugin returns a dictionary. The keys of the dictionary are the normalized field labels, or types. The keys will be alphanumeric and the underscore characters. If there are duplicate key, a number will be appended to the end of the key.

In the example above, a record is retrieved using the UID. The fields will be stored in a dictionary, in memory, using the register instruction. Since the allow attribute is used, the dictionary will only contain login and password .The field values can be accessed using the normal the templating in Ansible. The values will be stored as arrays. This is due to some fields returning arrays of the values, such as phone.

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

Either uids and titles is required.

Optional Attributes

  • cache - The record cache from the keeper_cache_records action.

  • allow - A list of keys to allow. If set, if the key is not in the list, it will not be inclued in the dictionary.

Plugin: keeper_set

The keeper_set plugin has the ability to write a value into an existing Keeper vault record. Example:

___
- name: Keeper Set
  hosts: my_hosts
  # Include line below if installed via ansible galaxy or use long plugin names.
  # collections: 
  #   - keepersecurity.keeper_secrets_manager
  
  tasks:
    - name: Get login name of new user.
      keeper_get:
        uid: RECORD UID
        field: login
      register: my_login
      
    - name: Add new user of remote machine.
      user:
        name: "{{ my_login.value }}"
        comment: "User {{ my_login.value }}"
      register: new_user
        
    - name: Update record with user's home directory in the Keeper Vault
      keeper_set:
        uid: RECORD UID
        custom_field: my_home_directory
        value: "{{ new_user.home }}"

In this example, a new user's login name is retreived. The new user is created on the remote system with the login name from the record. The home directory on the remote machine is then updated in the record.

The keeper_set action does not have the ability of set individual values of an array or complex values. It simplely replaces the existing value with a new value. For example, for a Hostname and Port field type there is no way to just update the port. The entire value including the hostName needs to be included in the object value.

keeper_set will set the update the record in the vault. It will not update the cache, if used. To update the cache, a step will need to run the keeper_cache_records action again with the UID or Title of the record that was updated.

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

  • notation - Use Keeper Notation to get the field from a record.

The attributes uids and titles can be used at the same time. At least one of them needs to be set.

Optional Attributes

  • cache - The record cache. Used for getting the record, will not update the cache.

  • field - Update the existing standard Keeper Vault record field.

  • custom_field - Update the existing custom Keeper Vault record field.

Plugin: keeper_create

The keeper_create plugin creates a record in the Keeper vault. See the Field/Record Types document for available record types, and the field types used to build the records. The action plugin will return the record_uid upon successful creation.

The Ansible variable keeper_app_owner_public_key is required to create a record. In the client-config.json, the JSON key is appOwnerPublicKey. If your configuration does not contain this key, create a new One-Time Access Token and initialize it.

Example:

---
- name: Keeper Create
  hosts: my_hosts
  
  tasks:
    - name: "Create A Record"
      keeper_create:
        shared_folder_uid: XXXXXX
        record_type: login
        generate_password: True
        password_complexity:
          length: 64
          allow_symbols: False
        title: "My New Record"
        note: "Created by Ansible"
        fields:
          - type: login
            value: johndoe@localhost
          - type: url
            value: https://localhost
        custom_fields:
          - type: text
            label: "My Custom Label"
            value: "My custom value"
      register: my_new_record

    - name: "New Record UID"
      debug:
        msg: "New record uid is {{ my_new_record.record_uid }}"

The following fields are required.

  • shared_folder_uid - The Shared Folder UID from the vault. The record will be created within this folder.

  • record_type - The type of record. This will included all the default record types. If the keeper_record_types is set, those record types can be used.

  • title - The title of record

The following fields are optional.

  • generate_password - If set to true, any password field where the password has not been set, will be populated with a random generated password.

  • password_complexity - Sets the complexity of the password. All parameters of password_complexity are optional.

    • length - Length of password. Defaults to 64.

    • allow_lowercase - Defaults to True. If set to False, no lowercase letters will be used.

    • allow_uppercase - Defaults to True. If set to False, no uppercase letters will be used.

    • allow_digits - Defaults to True. If set to False, no digits will be used.

    • allow_symbols - Defaults to True. If set to False, no symbols will be used.

    • filter_characters - A list of characters to exclude from the password. This allows to remove characters a services will reject. For example, '%' in SQL. If not set, the password will not be filtered.

  • notes - Attach a note to the record.

Password generation will use the following symbols: "!@#$%()+;<>=?[]{}^.,

Based on the Record Types, certain fields maybe required. Custom fields are optional. Both fields and custom_fields are an array of values.

  • fields/custom_fields

    • type - Field type

    • label - Label to display with the value.

    • value - Field value. Can be a string or dictionary based on field type.

Creating Custom Record Types

To create a record with a particular Custom Record Type, first export the custom record types using Keeper Commander and the record-type-info command. KSM does not sync down the custom type definitions, so this must be added directly to the playbook as a variable.

Keeper Commander will output a JSON Array ("content"). Only the JSON object is required.

Example:

My Vault> record-type-info --format json -lr "My Custom"
[
  {
    "recordTypeId": 18,
    "content": "{\"$id\":\"My Custom\",\"categories\":[\"login\"],
      \"description\":\"SSH key template\",\"fields\":[
        {\"$ref\":\"login\"},
        {\"$ref\":\"keyPair\"},
        {\"$ref\":\"password\",\"label\":\"passphrase\"},
        {\"$ref\":\"host\"},
        {\"$ref\":\"fileRef\"}]}"
  }
]

In your Ansible YAML file, add the value of the "content" object to the variable key called keeper_record_types. The variable is an array, and the JSON is to be treated as a string value. The pipe, after the array item, will treat the following JSON as a string. The variable will accept multiple record types.

Example:

- name: My Playbook
  collections:
   - keepersecurity.keeper_secrets_manager
  hosts: "my_hosts"
  vars:
    keeper_record_types:
      - |
        {
          "recordTypeId": 35,
          "content": "{\"$id\":\"My Custom\",\"fields\":[{\"$ref\":\"fileRef\",\"label\":\"File or Photo\"},{\"$ref\":\"login\",\"label\":\"Login\"},{\"$ref\":\"password\",\"label\":\"Password\",\"required\":true,\"enforceGeneration\":false,\"privacyScreen\":false,\"complexity\":{\"length\":8,\"caps\":0,\"lowercase\":0,\"digits\":0,\"special\":0}},{\"$ref\":\"text\",\"label\":\"System Login\",\"required\":true},{\"$ref\":\"secret\",\"label\":\"System Password / Pin Code\"},{\"$ref\":\"url\",\"label\":\"Keeper VPN Wiki\",\"required\":true},{\"$ref\":\"url\",\"label\":\"Password Best Practices FAQ's and Tips\",\"required\":true}]}"
        }

To check if this worked, the keeper_info plugin can be used to show which record types are available.

When creating a record of a particular custom type, the Ansible task will reference the record type name in the record_type parameter as seen below:

- name: "Create A Custom Record"
      keeper_create:
        shared_folder_uid: XXXXXXXXXXXX
        record_type: "My Custom"
        title: "Example Custom Record"
        note: "Created by Ansible"
        fields:
          - type: login
            label: Login
            value: johndoe@localhost
          - type: password
            label: Password
            value: "ABC123"
      register: my_new_record

Plugin: keeper_remove

v1.2.1 Released on: 10/27/2023

The keeper_remove plugin will remove a record from the Keeper vault.

---
- name: Keeper Remove
  hosts: my_hosts
  
  tasks:
    - name: Remove by UID
      keeper_remove:
        uid: RECORD UID
        
    - name: Remove by Title
      keeper_remove:
        title: RECORD TITLE
     

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

The attributes uid and title cannot be used at the same time. At least one of them needs to be set.

Optional Attributes

  • cache - The record cache from the keeper_cache_records action. The record will not be removed from the cache. The cache will be used for looking up the record title.

Plugin: keeper_password

The keeper_password plugin will generate a random password. The action plugin will return the password.

Example:

---
- name: Keeper Password
  hosts: my_hosts
  
  tasks:
    - name: Generate a long password
      keeper_password:
        length: 128
      register: long_password
    - name: Show long password
      debug:
        msg: "Long password {{ long_password.password }}"
        
    - name: Generate an all digit password
      keeper_password:
        length: 32
        allow_lowercase: False
        allow_uppercase: False
        allow_symbols: False
      register: digit_password
    - name: Show digit password
      debug:
        msg: "Digit password {{ digit_password.password }}"
        
    - name: Generate a PostgreSQL password (no % character)
      keeper_password:
        length: 64
        filter_characters: 
          - "%"
      register: pg_password
    - name: Show PostgreSQL password
      debug:
        msg: "PG password {{ pg_password.password }}"    

All parameters are optional. If no parameters are set, the defaults will be used.

  • length - Length of password. Defaults to 64.

  • allow_lowercase - Defaults to True. If set to False, no lowercase letters will be used.

  • allow_uppercase - Defaults to True. If set to False, no uppercase letters will be used.

  • allow_digits - Defaults to True. If set to False, no digits will be used.

  • allow_symbols - Defaults to True. If set to False, no symbols will be used.

  • filter_characters - A list of characters to exclude from the password. This allows to remove characters a services will reject. For example, '%' in SQL. If not set, the password will not be filtered.

Password generation will use the following symbols: "!@#$%()+;<>=?[]{}^.,

Based of record types, certain fields maybe required. Custom fields are optional. Both fields and custom_field are an array of values.

Plugin: keeper_lookup

The keeper_lookup plugin retrieves a field from the Keeper vault record and inserts the value into a text string. Example:

---
- name: Keeper Lookup
  hosts: my_hosts
  
  tasks:
    - name: Write login to file. Get record from the Keeper Vault
      copy:
        content: "My login is {{ lookup('keeper', uid='RECORD UID', field='login') }}"
        dest: "/tmp/my_login.txt"
      no_log: True
      
    - name: Using the array_index and value_key on complex values
      debug:
        msg: >-
          Second phone number is 
          {{ lookup('keeper', uid='RECORD UID', custom_field='My Phone', array_index=1, value_key='number') }}
 

In the example above, the first task the content of a file is created by templating the login name of a user from a Keeper record.

The second task displays as debug the second phone of number from a field with a complex value using the array_index and value_key task attributes. An array_index starts at 0, the next item in the araray will be 1, the next is 2, a so on. The value_key is the name of key in a key/pair dictionary.

Required Attributes

  • uid - A Keeper Vault record UID.

  • title - Title of a Keeper Vault records.

  • notation - Use Keeper Notation to get the field from a record.

The attributes uids and titles can be used at the same time. At least one of them needs to be set.

Optional Attributes

  • cache - The record cache. Used for getting multiple records, will not update the cache.

  • field - Update the existing standard Keeper Vault record field.

  • custom_field - Update the existing custom Keeper Vault record field.

  • file - Get the value from the files attach to the Keeper Vault record by file title.

  • allow_array - By default is False. If set to True, an array of values will be returned. This is needed if the field contains multiple values such as Phone numbers. If True, array_index and value_key will be ignored.

  • array_index - Defaults to 0. If the field value contains multiple values, this attribute will allow you to select which item to return. The first item will have the array_index of 0, and the next will be 1, etc.

  • value_key - If the field value is a complex object, this will allow you to select the key of the key/value pair to return.

Important Notes

  • To avoid leaking secret values when using the lookup plugin, add 'no_log: True' to the task. The stdout information will not be logged if the value is True.

  • If the plugin was installed by Ansible Galaxy the longer name is required for the lookup plugin (i.e. keepersecurity.keeper_secrets_manager.keeper). Listing collections appears not to work with lookup plugins.

  • To find out what fields and custom fields are available for a specific vault secret, use the Keeper Secrets Manager CLI "ksm secret get -u XXXX" command. More info here.

Plugin: keeper_init

The keeper_init plugin initialize a configuration from a one time access token. This is similar to the keeper_ansible --keeper_token command. The plugin accepts the following options.

  • token - The one time access token. It's best to template this value and pass in the value.

  • filename - The configuration file name to generate with config values. If not included, the configuration will not be created.

  • show_config - A flag to indicate if the configuration values should be returned in the task log. By default this is False. Only set to True if you are unable to generate the configuration via other methods or do not have access to a generated configuration file. If True, the configuration will be logged. This might not be a problem if running the playbook via the command line, however if running via Ansible Tower to will be log file which is retained.

---
- name: Keeper Lookup
  hosts: localhost
  connection: local
  
  tasks:
    - name: Init the one time access token
      keeper_init:
        token: "{{ keeper_token }}"
        filename: "{{ keeper_config_file }}"
        show_config: False

It's best not to hard code the token into the playbook since it's only good once. The token and the configuration file name can be passed into the playbook using the extra vars.

$ ansible-playbook my_init_playbook.yml \
  -e "keeper_token=US:XXX" \
  -e "keeper_config_file=my_keeper_config.yml"

The above will generate a file similar to the one below. The content of the file can be copied into a configuration file used by ansible, and optionally encrypted by ansible-vault.

keeper_app_key: +U5Ja ... 5FmXymVI=
keeper_client_id: Fokc ... WBdUPxPlBwzAKlMUgFZHqLg==
keeper_hostname: US
keeper_private_key: MIGHA ... yA7Oy
keeper_server_public_key_id: '10'

Ansible Galaxy Role

If the Keeper Secret Manager plugins were installed via Ansible Galaxy, a role called keeper_init_token was installed to initialize the one-time access token. This role can be used in a playbook.

---
- name: Initialize One Time Access Token
  hosts: localhost
  connection: local
  collections: keepersecurity.keeper_secrets_manager

  roles:
    - keeper_init_token

The role will use the following options set via extra variables.

  • keeper_token - Required one-time access token.

  • keeper_config_file - Generate a file containing the configuration. If not set, no file will be created.

  • keeper_show_config = Default False. If set to True, it will show the config in the log if verbosity is enabled.

Either keeper_config_file or keeper_show_config should be used, else the token will initialize and you will not be able to view the resulting configuration.

Plugin: keeper_info

The keeper_info action will display information about the Keeper ansible plugin. The results include a list of record types, field types, and versions of Python modules. In order to see the results, the verbosity level needed to be set at 1 or higher.

---
- name: Keeper Info
  hosts: localhost
  connection: local
  
  tasks:
    - name: Display Keeper Info
      keeper_info:

This can be used to verify custom record types are being picked up by the plugins.

Plugin: keeper_cleanup

The keeper_cleanup plugin is used to clean up any files created by the keeper plugins. This is mainly used to delete a cache file, if you are using it. Disaster Recovey cache files are used when there are network problems as a fall back to get records. If you are running Ansible secret environment, there is no need to remove the Disaster Recovey cache. However this plugin gives you the ability to do so.

- name: Keeper Lookup
  hosts: localhost
  connection: local
  vars:
    keeper_use_cache: True
  
  tasks:
    ... bunch of tasks
    
    - name: Remove the cache file
      keeper_cleanup:
    

Plugin: keeper_redact

The keeper_redact stdout callback plugin is used to redact secrets from the standard out logs. This will work for the keeper_redact stdout callback plugin is used to redact secrets from the standard out logs. This will work for the keeper_copy and keeper_get plugins. It will not redact secret values for keeper_lookup. For keeper_lookup, use the no_log: True directive.

See How do I keep secrets data in my playbook? Using no_log can hide all logging from a task. This plugin is for when you just want secrets returned by the Keeper Secrets Manager plugins to be hidden/redacted.

The keeper_redact plugin will not work with Ansible Tower since it had its own stdout callback plugin to stream the log as the job runs. Highly recommend using the no_log option when you do not wish show information in the log.

To use the keeper_redact plugin, enable it in your ansible.cfg.

[defaults]
stdout_callback = keeper_redact
# Use long name if install via Ansible Galaxy
# stdout_callback = keepersecurity.keeper_secrets_manager.keeper_redact

For example, the following task would return all the phone numbers in the custom field MyPhoneNumbers and place them into the variable phone_numbers.

    - name: "Get Phone Numbers"
      keeper_get:
        uid: OlLZ6JLjnyMOS3CiIPHBjw
        custom_field: MyPhoneNumbers
        allow_array: True
      register: phone_numbers

If the playbook was run with any verbosity, the values being placed into the variable would be displayed. This would leak the secrets to the log. If the keeper_redact stdout callback plugin is enabled, the values in the log would be redacted.

TASK [Get Phone Numbers] **************************************************
ok: [my_server] => {
    "value": [
        {
            "number": "****",
            "type": "****",
            "ext": "****"
        },
        {
            "region": "****",
            "number": "****",
            "ext": "****",
            "type": "****"
        }
    ],
    "changed": false
}

Ansible Vault Password Retrieval

You can use the Keeper Secret Manager CLI ("ksm") to provide the decryption password for your Ansible vaults. This is done using the ANSIBLE_VAULT_PASSWORD_FILE environment variable or the vault_password_file in the ansible.cfg field to specify an executable file that will return a password.

A executable shell script can be created that returns the password using the "ksm" secret notation (learn more about ksm secret notation). For example, the below script will output a specific secret password for the given Record UID:

#!/bin/sh
ksm secret notation keeper://XXXX/field/password

Replace XXXX with the Vault Record UID. Running this script simply outputs the secret password.

To override the environmental variable "ANSIBLE_VAULT_PASSWORD_FILE", execute the following, replacing /path/to/script with the location of the above script.

$ ANSIBLE_VAULT_PASSWORD_FILE=/path/to/script.sh ansible-playbook playbook_with_vault.yml

Now, when Ansible needs to decrypt any vaults used by playbook_with_vault.yml, it will execute that shell script. The shell script will retrieve the password from the Keeper Vault.

Logging

By default, the Ansible plugins will only display errors. If you use the Ansible verbosity level, different SDK logging will be displayed. An Ansible verbosity level of -v will display any SDK messages INFO and higher, while a verbosity level of -vvv will display any SDK messages DEBUG and higher.

Troubleshooting

__NSPlaceholderDate in progress in another thread when fork() called error.

This appears to be specific to Ansible running on MacOS. While running a playbook you may get the following error:

objc[6763]: +[__NSPlaceholderDate initialize] may have been in progress in 
another thread when fork() was called. We cannot safely call it or ignore 
it in the fork() child process. Crashing instead. Set a breakpoint on 
objc_initializeAfterForkError to debug

This is known problem with Ansible. This can be fixed with the following environmental variable.

OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ansible-playbook ...

Missing Configuration file

TASK [Copy file from Keeper into the file] ********************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: Exception: Keeper Ansible error: There is no config file and the Ansible variable contain no config keys. Will not be able to connect to the Keeper server.
fatal: [localhost]: FAILED! => {"msg": "Unexpected failure during module execution.", "stdout": ""}

Ansible Tower

A collection of Ansible plugins that interact with your Keeper account and can be used in your Ansible Tower automations.

Features

  • Store Secrets Manager configurations securely in Ansible Tower

  • Use Ansible Tower to manager and launch Ansible projects utilizing the Secrets Manager Ansible plugin which features:

    • Retrieving secrets from the Keeper vault to use in Ansible Playbooks

    • Updating the value of secrets in the Keeper Vault from Ansible

    • Copying files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

KSM Configuration

The first step in using Ansible Tower with Keeper Secrets Manager is to get and initialize a Base64 configuration. The Secret Manager Configuration document will explain how to get a configuration using the Keeper Secret Manager CLI or Commander CLI.

Using Commander CLI, add a new device can generate a Base64 configuration without using a one time access token.

keeper secrets-manager client add --app MyApp --config-init b64

The Keeper Secrets Manager CLI requires a one-time access token. This can be obtained from the Web Vault by adding a new device to an application.

$ ksm init default US:XXXX

Another way using the keeper_init_token role included in the Keeper Secrets Manager collection, which can used after Ansible Tower is setup. An example will appear at the end of this document.

The Base64 configuration can be added to the inventories, hosts, or templates variables sections. It can also be added to the playbook repository as an Ansible secret. The variable name is keeper_config.

Vault Credential

With the Base64 KSM configuration we need to create a vault credential. Under the Resources menu, select Credentials and click Add.

Give your Vault Credential a name, select Vault from the Credential Type drop-down, type in the password that was used to encrypt the secrets.yml file into the Vault Password field, then click Save.

The credential will be used when the Template is setup.

Execution Environment

To use the Keeper Secrets Manager plugins in Ansible Tower an Execution Environment containing the Keeper Secrets Manager SDK is required. This SDK is included in the Docker image keeper/keeper-secrets-manager-tower-ee. In your instance of Ansible Tower, select Execution Environment in the Administration menu, then click Add.

The Image value is docker.io/keeper/keeper-secrets-manager-tower-ee:latest or docker.io/keeper/keeper-secrets-manager-tower-ee:<tag> if there is a specific tag version.

The value for Pull should be set to Always pull container before running is you are using the latest tag. If you pin the tag to a specific tag version of keeper/keeper-secrets-manager-tower-ee then set the value to Only pull the image if not present before running.

Projects

Playbook Repository

Using the Keeper Security Manager collection from Ansible Galaxy

To use the Keeper Secrets Manager plugins in your projects, create a collections directory in your source repository, if one does not already exists. Then create, or add to, the file requirements.yml the following value.

---
collections:
  - keepersecurity.keeper_secrets_manager

Storing the KSM Configuration

The Base64 KSM configuration can be stored in numerous places inside of Ansible Tower like in the inventories, hosts, and templates. The configuration is encrypted when stored in these locations.

For this project, the KSM configuration will be stored as an encrypted secret in the source repository. Add a YAML file called secrets.yml in a directory called defaults located in the root directory of the repository.

In this file add a key called keeper_config with the Base64 configuration as it's value.

---
keeper_config: ewogICAgImNsaWVudElk ... Y0tleUlkIjogIjEwIgp9

Then encrypt the secrets.yml file using ansible-vault.

Remember the password, it will be needed in Tower for a Vault Credential.

$ ansible-vault encrypt secret.yml
New Vault password:
Confirm New Vault password:
Encryption successful

At this point, if you look at your secrets.yml file, it should be encrypted.

Playbook

The directory structure should look like the following.

$ tree
.
├── collections
│   └── requirements.yml
├── defaults
│   └── secrets.yml
├── playbook_1.yml
└── playbook_2.yml

For our playbooks, the Keeper Secrets Manager collection is added to the playbook collections. The first task is to include the secrets.yml using the built-in action include_vars. That task also includes no_log: True to prevent the KSM configuration from being logged. This task needs to be performed before any of the plugins from the Keeper Secrets Manager collection.

Ansible Tower uses it's own stdout callback plugin. So using keeper_redact will not work. It's important to add no_log: True to tasks that may display secrets in the log.

---
- name: Playbook One
  hosts: all
  collections: 
    - keepersecurity.keeper_secrets_manager

  tasks:
    - include_vars:
        file: "defaults/secrets.yml"
      no_log: True

    - name: "Make User SSH Directory, if does not exists"
      file:
        path: "/home/user/.ssh"
        state: directory
        recurse: yes

    - name: "Copy SSH Keys"
      keeper_copy:
        notation: "OlLZ6JLjnyMOS3CiIPHBjw/field/keyPair[{{ item.notation_key }}]"
        dest: "/home/user/.ssh/{{ item.filename }}"
        mode: "0600"
      loop:
        - { notation_key: "privateKey", filename: "id_rsa" }
        - { notation_key: "publicKey",  filename: "id_rsa.pub" }

Project

Once you have added the collection to your source repository, a new Project can be created.

Make sure to select the Execution Environment that you create that uses the keeper/keeper-secrets-manager-tower-ee image.

In the example above, the source repository was Git with the appropriate details. Your company may use a different source control.

After it is saved, sync the playbooks to your Ansible Tower instance.

Template

In your instance of Ansible Tower, select Templates in the Resources menu, then click Add.

For Projects select the project that was just created that contain the playbooks. For Execution Environment select the execution environment what contains the Keeper Secrets Manager Tower EE docker image. For Playbook select a playbook from your source repository.

For Credentials select the Vault credential that will be used to decrypt the secrets.yml file in the Project's source repository. You can also select the credential to use for connection to your inventory servers.

Finish by clicking the Save button at the bottom of the page.

Launching a Template

The last step is to launch a template to create a job.

The include_vars task will import the KSM Base64 Configuration and decrypt it. The no_log: True will hide the configuration from the log. If it is not included, the configuration will be logged and viewable by anyone who has access to Ansible Tower.

With the configuration now in the available variables, the keeper_copy action can retrieve the public and private SSH key from the Keeper Vault and copy them into location on the remote machine.

See the Ansible Plugin documentation for all the Secrets Manager capabilities available to Ansible

AWS CLI Credential Process

Protect your AWS Access Keys with Keeper Secrets Manager

About

By default, the AWS CLI uses credentials stored in plaintext in ~/.aws/credentials. With this credential process, you can now use the Keeper Vault to store your AWS credentials, removing the need to have them on disk.

Instead, AWS will use this executable to securely fetch your AWS credential from your Vault using the Keeper Secrets Manager (KSM).

Features

  • Use a vaulted AWS Access Key to authenticate to the AWS CLI.

Prerequisites

In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with an Access Key shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • This integration only accepts JSON format configurations

  • The AWS CLI v2 installed

Setup

Vault

The first step in the setup of the integration is to add you AWS Access Key ID and your Secret Access Key to a record in your Vault. There is no built-in record type for this kind of secret; however, you can create a custom record for this purpose alone.

In order to create new custom Record Types, the user must be in an Administrative role with the "Manage Record Types in Vault" permission activated.

Note: Field names are case-sensitive.

An example of the minimum fields needed for the custom record.

Once you have created your custom field, you can now use it to create a record for your AWS Access Key. This record should be stored in a shared folder that your KSM application has permission to access.

Once safely stored, you can delete the Access Key credentials from your AWS credential file.

KSM

The integration expects a KSM Application Configuration file at either .config/keeper/aws-credential-process.json or aws-credential-process.json relative to the user's home directory. It must have access to a Shared Folder containing the required AWS Access key.

For help in obtaining a KSM configuration in JSON format, follow these instructions. After creating a new device get corresponding config.json and copy it into user's home folder as aws-credential-process.json

AWS Config

Download the latest version of the keeper-aws-credential-process executable from the GitHub releases page and store that in a convenient location.

Now in your AWS configuration file, which is usually located at ~/.aws/config, add the following line to any profile you are using via the CLI.

# Add the UID for your AWS Access Key
#credential_process = /path/to/keeper-aws-credential-process --uid <Record UID>
credential_process = /opt/keeper-aws-credential-process-v0.1.1_linux_amd64  --uid <Record UID>

Make sure there's no residual aws cli configuration left on the machine which may be picked up automatically or on credential process misconfiguration.

Usage

Once configured as above, the AWS CLI will automatically fetch your authentication credential from the Keeper Vault. You can test that it works by using any CLI command in which you have an appropriate IAM role for, such as:

# List all s3 buckets
aws s3 ls

If the command completes without error, congratulations, you are now fully set up.

Feature Request / Report an Issue

This Credential Process is open source and can be found on GitHub. If you need to report a bug or would like to request a feature to support more authentication use cases, please create a GitHub issue.

AWS Secrets Manager Sync

Sync secrets from the Keeper Vault with AWS Secrets Manager

About

The Keeper Secrets Manager CLI tool sync command allows you to push secrets from the Keeper Vault to a target AWS Secrets Manager account, overwriting the existing values in the target location. This allows the Keeper Vault to be the single source of truth for any services or scripts in AWS that utilize AWS Secrets Manager.

Features

  • Use secrets from the Keeper Vault as the source of truth for AWS Secrets Manager

  • Seamlessly start using secrets from the Keeper Vault with your existing AWS scripts and services

Prerequisites

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper subscription

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An AWS account with AWS Secrets Manager, and the ability to create IAM security credentials

Setup

1. Configure Keeper Secrets Manager CLI

You can skip this step if the KSM CLI is already configured on your machine.

To configure the KSM CLI tool, a profile needs to be created with the Keeper Secrets Manager One Time Access Token.

The simplest way to do this is to initialize the default profile with the following command:

ksm profile init <TOKEN>

For information on creating multiple profiles and other options, see the profile documentation

2. Set AWS Permissions

To use the KSM sync to AWS, AWS Secrets Manager requires standard IAM security credentials with SecretsManagerReadWrite enabled for the entire vault or on individual keys to sync.

arn:aws:iam::aws:policy/SecretsManagerReadWrite

See the Amazon instructions for creating Access Keys:

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html

3. Create AWS Credentials Record

The KSM CLI needs the credentials for the AWS account to set secrets. These credentials are stored in a Keeper record which the CLI tool can access using Keeper Secrets Manager.

Record fields with the following labels are required on the credentials record:

"AWS Access Key ID" "AWS Secret Access Key" "AWS Region Name"

(Method 1) Create an AWS Credentials Custom Record Type

A custom record type can be created with the required fields, which makes it easy and clean to create a record.

To create a custom record type, go to the "Custom Record Types" tab in the Keeper Vault and hit "Create Type". Create a new record type with hidden fields that have the correct field label, then click "Publish" to create the new record type.

AWS Credentials Record Type Definition

Then simply create a new record of the AWS Credentials type and enter the details into the corresponding fields.

Make sure this new record is moved to a Shared Folder that is associated with your Secrets Manager application.

(Method 2) Add Custom Fields

To create a credentials record without creating a new record type, the required fields can be added as custom fields to a standard record.

Create a new record of any type, then add Custom Fields of the 'Hidden Field' type for each required AWS field. Click "Edit Label" to change the labels to the corresponding field name.

Any record type will work, but the "File Attachment" standard record type has no fields and will be cleaner looking when custom fields are added

Credentials fields as custom fields

Then fill in each custom field and hit "Save" to save the record.

4. Create Value Mappings

The KSM CLI sync command identifies which values to set using mappings that are defined on the command call. For each mapping passed to the command, a value with the given name will be populated with the given value from the Keeper Vault.

These mappings follow this format:

--map "VALUE KEY" "KEEPER NOTATION"

VALUE KEY is the key name that the value will be assigned in AWS Secrets Manager

KEEPER NOTATION is a Keeper notation query of a value from a keeper record to set to the key

Keeper notation is a query notation used by Keeper Secrets Manager to identify specific record values. The notation follows the general format of: UID/[field|custom_field]/fieldname for example: ae3d[...]d22e/field/password

See the Keeper Notation documentation for more information

Note that full record UIDs are not given in these examples

Full Mapping Example: --map "MySQL_PWD" "jd3[...]i-fd/field/password"

Multiple mappings can be added to a single sync command --map "MySQL_PWD" "jd3[...]i-fd/field/password" --map "MySQL_Login" "jd3[...]i-fd/field/login"

Ensure that the records referenced by the Keeper Notation queries are in a shared folder that is shared with your Secrets Manager application

KSM sync is now ready to run

Run Sync

To run the sync, use the KSM CLI sync command with the credentials record and value mapping.

1. Construct the Command

Put together the KSM sync command with the AWS type. The format looks like the following:

ksm sync --type aws --credentials [UID] --map [...] --map [...]

2. Run a Dry-Run

The sync command supports running a dry-run which will identify all changes that will be made to your AWS Secrets Manager values without actually pushing the values or making changes. Use this to make sure your mapping queries are constructed properly.

ksm sync --type aws --credentials [UID] --map [...] --map [...] --dry-run

3. Run the Sync

When ready, run the sync command without the dry-run option. This will push values from your Keeper Vault to AWS Secrets Manager

TIP: you can use -m as short hand for --map

ksm sync --type aws --credentials [UID] -m [...] -m [...]

AWS KMS Encryption

Protect Secrets Manager connection details with AWS KMS

Keeper Secrets Manager integrates with AWS KMS in order to provide encryption for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all your secret credentials.

Features

  • Encrypt and Decrypt your Keeper Secrets Manager configuration files with AWS KMS

  • Protect against unauthorized access to your Secrets Manager connections

  • Requires only minor changes to code for immediate protection. Works with all Keeper Secrets Manager SDK functionality

Prerequisites

  • Supports the Java Secrets Manager SDK

  • Requires AWS-KMS and AWS-Auth packages

  • Supports Java 11 and above

  • Supports the JavaScript Secrets Manager SDK

  • Requires aws-sdk/client-kms package

  • Supports the Python Secrets Manager SDK

  • Requires boto3 package

  • Supports the .Net Secrets Manager SDK

  • Requires AWSSDK.KeyManagementService

  • Supports the GoLang Secrets Manager SDK

  • Requires aws-sdk-v2

Setup

1. Install Module

Setting up project using Gradle or Maven

Gradle

repositories {
  mavenCentral()
}

dependencies {
  implementation("com.keepersecurity.secrets-manager:aws:1.0.0")
  implementation("com.keepersecurity.secrets-manager:core:17.0.0")
  implementation ("software.amazon.awssdk:kms:2.20.28")
  implementation ("software.amazon.awssdk:auth:2.20.28")
  implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
  implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
  implementation("com.google.code.gson:gson:2.12.1")
  implementation("org.slf4j:slf4j-api:1.7.32"){
      exclude("org.slf4j:slf4j-log4j12")
  }
  implementation("ch.qos.logback:logback-classic:1.2.6")
  implementation("ch.qos.logback:logback-core:1.2.6")
  implementation("org.bouncycastle:bc-fips:1.0.2.4")
}

Maven

<!-- KMS-core -->
<dependency>
 <groupId>com.keepersecurity.secrets-manager</groupId>
 <artifactId>aws</artifactId>
 <version>1.0.0</version>
</dependency>
<dependency>
 <groupId>com.keepersecurity.secrets-manager</groupId>
 <artifactId>core</artifactId>
 <version>17.0.0</version>
</dependency>

<!-- aws-kms -->
   	<dependency>
   		<groupId>software.amazon.awssdk</groupId>
   		<artifactId>kms</artifactId>
   		<version>2.20.28</version>
   	</dependency>
   		
   	<!-- aws-auth -->
   	<dependency>
   		<groupId>software.amazon.awssdk</groupId>
   		<artifactId>auth</artifactId>
   		<version>2.20.28</version>
   	</dependency>
   	
   	<!--gson -->
   	<dependency>
   	    <groupId>com.google.code.gson</groupId>
   	    <artifactId>gson</artifactId>
   	    <version>2.12.1</version>
   	</dependency>

   	<!--jackson-core -->
   	<dependency>
   		<groupId>com.fasterxml.jackson.core</groupId>
   		<artifactId>jackson-core</artifactId>
   		<version>2.18.2</version>
   	</dependency>
   	
   	<!--jackson-databind -->
   	<dependency>
   		<groupId>com.fasterxml.jackson.core</groupId>
   		<artifactId>jackson-core</artifactId>
   		<version>2.18.2</version>
   	</dependency>
   	
   	<!-- slf4j-api -->
   	<dependency>
   		<groupId>org.slf4j</groupId>
   		<artifactId>slf4j-api</artifactId>
   		<version>1.7.32</version>
   		<scope>runtime</scope>
   	</dependency>

   	<!-- logback-classic -->
   	<dependency>
   		<groupId>ch.qos.logback</groupId>
   		<artifactId>logback-classic</artifactId>
   		<version>1.2.6</version>
   		<scope>compile</scope>
   	</dependency>

   	<!-- logback-core -->
   	<dependency>
   		<groupId>ch.qos.logback</groupId>
   		<artifactId>logback-core</artifactId>
   		<version>1.2.6</version>
   		<scope>compile</scope>
   	</dependency>
   	
   	<!-- bc-fips -->
   	<dependency>
   		<groupId>org.bouncycastle</groupId>
   		<artifactId>bc-fips</artifactId>
   		<version>1.0.2.4</version>
   	</dependency>
   	

The Secrets Manager AWS Key Management Service Integration can be installed using npm

npm install @keeper-security/secrets-manager-aws

The Secrets Manager HSM modules are located in the Keeper Secrets Manager storage module which can be installed using pip

pip3 install keeper-secrets-manager-storage

boto3 is a prerequisite for the AWS KSM integration. Install it to your machine using pip.

pip install boto3

The Secrets Manager AWS Key Management Service Integration can be installed using

dotnet add package Keeper.SecretsManager.AWSKeyManagement

The Secrets Manager AWS Key Management Service Integration can be installed using

go get github.com/keeper-security/secrets-manager-go/integrations/aws

2. Configure AWS Connection

By default the boto3 library will utilize the default connection session setup with the AWS CLI with the aws configure command. If you would like to specify the connection details, the two configuration files located at ~/.aws/config and ~/.aws/credentials can be manually edited.

See the AWS documentation for more information on setting up an AWS session: https://docs.aws.amazon.com/cli/latest/reference/configure/

Alternatively, configuration variables can be provided explicitly as an access key using the AwsSessionConfig data class and providing aws_access_key_id , aws_secret_access_key and aws_session_token variables.

You will need an AWS Access Key to use the AWS KMS integration.

For more information on AWS Access Keys see the AWS documentation: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/

3. Add AWS KMS Storage to Your Code

Once AWS connection has been configured, You can fetch the Key to encrypt / decrypt KSM configuration using integration and you need to tell the Secrets Manager SDK to utilize the KMS as storage. Using Specified Connection credentials

To do this, use AwsKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, AwsSessionConfig, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import com.keepersecurity.secretmanager.aws.kms.AwsKeyValueStorage;
import com.keepersecurity.secretmanager.aws.kms.AwsSessionConfig;
import com.keepersecurity.secretsManager.core.InMemoryStorage;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;

import software.amazon.awssdk.regions.Region;

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

class Test {
	public static void main(String args[]){
		String keyId = "<Key ID>";
		String awsAccessKeyId = "<AWS Access ID>";
		String awsSecretAccessKey = "<AWS Secret>";
		String oneTimeToken = "[One Time Token]";
		Region region = Region.<cloud-region>;
		String profile = null OR "DEFAULT";     //set profile (ex. DEFUALT/UAT/PROD) if ~/.aws/config is set
		String configFileLocation = "client_config_test.json";
		try{
			//set AWS configuration, It can be null if profile is set for aws credentials
			AwsSessionConfig sessionConfig = new AwsSessionConfig(awsAccessKeyId, awsSecretAccessKey);
			//Get Storage 
			AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, null, region);
			initializeStorage(awskvstorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(awskvstorage);
			//getSecrets(OPTIONS);
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, AWS Session credentials - AWSSessionConfig , as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

import { AWSKeyValueStorage, AWSSessionConfig, LoggerLogLevelOptions } from "@keeper-security/secrets-manager-aws";
import { initializeStorage, getSecrets } from "@keeper-security/secrets-manager-core";


const getKeeperRecordsAWS = async () => {

	const accessKeyId = "<YOUR AWS ACCESS KEY>>";
	const secretAccessKey = "<YOUR AWS SECRET_ACCESS_KEY>";
	const regionName = "<YOUR AWS REGION>";
	const logLevel = LoggerLogLevelOptions.Debug;
	const configPath = "client-config-path.json";
	
	const awsSessionConfig = new AWSSessionConfig(accessKeyId, secretAccessKey, regionName);
	const keyId = 'arn:aws:kms:ap-south-1:<accountName>:key/<keyId>';
	const storage = await new AWSKeyValueStorage(keyId, configPath, awsSessionConfig, logLevel).init();
	
	const oneTimeToken = "<one time token>";

	await initializeStorage(storage, oneTimeToken);
	const { records } = await getSecrets({ storage: storage });

	const firstRecord = records[0]
	const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
	console.log(firstRecordPassword.value[0])
};
getKeeperRecordsAWS();

To do this, use AwsKmsKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, AwsSessionConfig, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="us-east-2")

config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.get_secrets()

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, AwsSessionConfig, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

using System;
using System.Linq;
using System.Threading.Tasks;
using SecretsManager;
using AWSKeyManagement;

public class Program
{
	private static async Task getOneIndividualSecret()
	{
		var accessKeyId = "<ACCESS_KEY_ID>";
		var secretAccessKey = "<SECRET_ACCESS_KEY>";
		var regionName = "<AWS_REGION_STRING";

		var keyId = "<KEY_ID_1>";
		var path = "<KEEPER_CONFIG_FILE_PATH>";
		var dotnet_access_token = "<ONE_TIME_TOKEN>";

		var awsSessionConfig = new AWSSessionConfig(accessKeyId, secretAccessKey, regionName);

		var aws_storage = new AWSKeyValueStorage(keyId, path, awsSessionConfig);

		SecretsManagerClient.InitializeStorage(aws_storage, dotnet_access_token);

		var options = new SecretsManagerOptions(aws_storage);
		var records_1 = await SecretsManagerClient.GetSecrets(options);
		records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
	}

	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, AwsSessionConfig, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

package main

import (
	"encoding/json"
	"fmt"

	"github.com/keeper-security/secrets-manager-go/core"
	awskv "github.com/keeper-security/secrets-manager-go/integrations/aws"
)

func main() {

	clientID := "<Some Client ID>"
	clientSecret := "<Some Client Secret>"
	region := "<Cloud Region>"
	keyARN := "arn:<partition>:kms:<region>:<account-id>:key/<key-id>"
	oneTimeToken := "one time token"
	ksmConfigFileName := ""

	// Initialize the AWS Key Vault Storage
	cfg := awskv.NewAWSKeyValueStorage(ksmConfigFileName, keyARN, &awskv.AWSConfig{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Region:       region,
	})

	clientOptions := &core.ClientOptions{
		Token:  oneTimeToken,
		Config: cfg,
	}

	fmt.Printf("Client ID in config: %v\n", cfg.Get(core.KEY_CLIENT_ID))

	secrets_manager := core.NewSecretsManager(clientOptions)
	// Fetch secrets from Keeper Security Vault
	record_uids := []string{}
	records, err := secrets_manager.GetSecrets(record_uids)
	if err != nil {
		// do something
		fmt.Printf("Error while fetching secrets: %v", err)
	}

	for _, record := range records {
		// do something with record
		fmt.Println(record.Title())
	}

}

Using Default Connection

To do this, use AwsKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import com.keepersecurity.secretmanager.aws.kms.AwsKeyValueStorage;
import com.keepersecurity.secretmanager.aws.kms.AwsSessionConfig;
import com.keepersecurity.secretsManager.core.InMemoryStorage;
import com.keepersecurity.secretsManager.core.SecretsManager;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;

import software.amazon.awssdk.regions.Region;

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

class Test {
	public static void main(String args[]){
		String keyId = "<Key ID>";
		String awsAccessKeyId = "<AWS Access ID>";
		String awsSecretAccessKey = "<AWS Secret>";
		String oneTimeToken = "[One Time Token]";
		Region region = Region.<cloud-region>;
		String profile = null OR "DEFAULT";     //set profile (ex. DEFUALT/UAT/PROD) if ~/.aws/config is set
		String configFileLocation = "client_config_test.json";
		try{
			//set AWS configuration, It can be null if profile is set for aws credentials
			AwsSessionConfig sessionConfig = new AwsSessionConfig(awsAccessKeyId, awsSecretAccessKey);
			//Get Storage 
			AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
			initializeStorage(awskvstorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(awskvstorage);
			//getSecrets(OPTIONS);
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID , as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

import { AWSKeyValueStorage } from "@keeper-security/secrets-manager-aws";
import { initializeStorage, getSecrets } from "@keeper-security/secrets-manager-core";


const getKeeperRecordsAWS = async () => {

	const configPath = "client-config-path.json";
	
	const keyId = 'arn:aws:kms:ap-south-1:<accountName>:key/<keyId>';
	const storage = await new AWSKeyValueStorage(keyId, configPath).init();
	
	const oneTimeToken = "<one time token>";

	await initializeStorage(storage, oneTimeToken);
	const { records } = await getSecrets({ storage: storage });

	const firstRecord = records[0]
	const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
	console.log(firstRecordPassword.value[0])
};
getKeeperRecordsAWS();

To do this, use AwsKmsKeyvalueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage

key_id = 'c5[...]576'
    
config = AwsKmsKeyValueStorage(key_id, 'client-config.json') # default session
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.get_secrets()

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

using System;
using System.Linq;
using System.Threading.Tasks;
using SecretsManager;
using AWSKeyManagement;

public class Program
{
	private static async Task getOneIndividualSecret()
	{
		var keyId = "<KEY_ID_1>";
		var path = "<KEEPER_CONFIG_FILE_PATH>";
		var dotnet_access_token = "<ONE_TIME_TOKEN>";

		var aws_storage = new AWSKeyValueStorage(keyId, path);

		SecretsManagerClient.InitializeStorage(aws_storage, dotnet_access_token);

		var options = new SecretsManagerOptions(aws_storage);
		var records_1 = await SecretsManagerClient.GetSecrets(options);
		records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
	}

	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}

To do this, use AWSKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an AWS Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by AWS KMS.

package main

import (
	"fmt"

	"github.com/keeper-security/secrets-manager-go/core"
	awskv "github.com/keeper-security/secrets-manager-go/integrations/aws"
)

func main() {

	keyARN := "arn:<partition>:kms:<region>:<account-id>:key/<key-id>"
	oneTimeToken := "one time token"
	ksmConfigFileName := "<config file name>"

	// Initialize the AWS Key Vault Storage
	cfg := awskv.NewAWSKeyValueStorage(ksmConfigFileName, keyARN, nil)

	clientOptions := &core.ClientOptions{
		Token:  oneTimeToken,
		Config: cfg,
	}

	fmt.Printf("Client ID in config: %v\n", cfg.Get(core.KEY_CLIENT_ID))

	secrets_manager := core.NewSecretsManager(clientOptions)
	// Fetch secrets from Keeper Security Vault
	record_uids := []string{}
	records, err := secrets_manager.GetSecrets(record_uids)
	if err != nil {
		// do something
		fmt.Printf("Error while fetching secrets: %v", err)
	}

	for _, record := range records {
		// do something with record
		fmt.Println(record.Title())
	}

}

Using the AWS KMS Integration

Once setup, the Secrets Manager AWS KMS integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the AWS KMS APIs in order to manage the decryption of the configuration file when run.

Additional Options

Change Key

We can change key that is used for encrypting the configuration, examples below show the code needed to use it

String newkeyId = "<New-Key-ID>";
AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
awskvstorage.changeKey(newkeyId)
const storage = await new AWSKeyValueStorage(keyId,config_path).init()
await initializeStorage(storage, oneTimeToken);

// do all process needed if any or change directly
await storage.changeKey(keyId2);
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="<region>")

new_key_id = "<new_key_id>"
config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.change_key(new_key_id)
    using Microsoft.Extensions.Logging;

    var awsSessionConfig2 = new AWSSessionConfig();
    var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.SetMinimumLevel(LogLevel.Debug);
            builder.AddConsole();
        });

    var logger = loggerFactory.CreateLogger<AWSKeyValueStorage>();

    var aws_storage = new AWSKeyValueStorage(keyId, path, awsSessionConfig2,logger);
updatedKeyARN := "arn:<partition>:kms:<region>:<account-id>:key/<key-id>"
isChanged, err := cfg.ChangeKey(updatedKeyARN, nil)
if err != nil {
    fmt.Printf("Error while changing key: %v", err)
}

Decrypt Config

We can decrypt the config if current implementation is to be migrated onto a different cloud or if you want your raw credentials back. The function accepts a boolean which when set to true will save the decrypted configuration to file and if left false, will just return decrypted configuration.

AwsKeyValueStorage awskvstorage =  new AwsKeyValueStorage(keyId, configFileLocation, profile, sessionConfig, region);
awskvstorage.decryptConfig(true) // Set true as a parameter to extract plaintext and save config as a plaintext.
//OR 
awskvstorage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
const storage = await new AWSKeyValueStorage(keyId,config_path).init();
await storage.decryptConfig(); 
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_aws_kms import AwsKmsKeyValueStorage
 
aws_session_cfg = AwsSessionConfig(
    aws_access_key_id="AK[...]FIF",
    aws_secret_access_key="/[...]/g3",
    region_name="<region>")

config = AwsKmsKeyValueStorage(
   key_id='e9[...]567',
   config_file_location='client-config.json',
   aws_session_config=aws_session_cfg)
 
secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)
all_records = secrets_manager.decrypt_config(True)
var conf = await aws_storage.DecryptConfigAsync(false);
Console.WriteLine(conf);   
cfg := awskv.NewAWSKeyValueStorage(ksmConfigFileName, keyARN, &awskv.AWSConfig{
		ClientID:     clientID,
		ClientSecret: clientSecret,
		Region:       region,
	})
decryptedConfig, err := cfg.DecryptConfig(true)

You're ready to use the KSM integration 👍

Check out the KSM SDKs documentation for more examples and functionality

Azure DevOps Extension

Keeper Secrets Manager integration into Azure DevOps for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault from an Azure DevOps pipeline

  • Set secret credentials as build arguments or environment variables

  • Copy secure files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Azure DevOps integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Azure DevOps integration accepts JSON and Base64 format configurations

Installation

Install the Keeper Secrets Manager Extension

Download from the Visual Studio Marketplace here or search for "Keeper Secrets Manager"

Enable the extension for your Azure organization by selecting an organization and clicking "Download".

Access Secrets From Azure Pipelines

In order to access secrets from the Keeper Vault, add a task to your Azure Pipelines YAML configuration file. Then query your records for the desired fields. Secret queries use Keeper Notation and have the following syntax KeeperNotation > destination where the destination location is defined by its prefix var:, out: or file: see the examples below.

Since v1.0.4 extension allows use of a search by title syntax, where UID portion could be replaced with the record title and must be escaped according to Keeper Notation rules then it must follow YAML format specifications for escaping special characters.

Create a Keeper Secrets Manager Task

Keeper Secrets Manager tasks look like this:

- task: ksmazpipelinetask@1
  inputs:
    keepersecretconfig: $(secret_config)
    secrets: |
      6ya_fdc6XTsZ7i4x9Jcodg/field/password > var:var_password
      6ya_fdc6XTsZ7i4x9Jcodg/field/password > out:out_password
      6ya_fdc6XTsZ7i4x9Jcodg/field/password > out_password2
      6ya_fdc6XTsZ7i4x9Jcodg/file/cert.pem > file:/tmp/mycert.pem

In this example, 6ya_fdc6XTsZ7i4x9Jcodg is the Record UID. In order to add a task, you can create a task using a Task Form, or add it manually.

Add Task Using a Task Form

Search the Tasks menu for "Keeper Secrets Manager" to open the task form.

To fill in the task form and create a Keeper Secrets Manager Task, you will need:

  • A Keeper Secrets Manager Configuration

    • The Azure DevOps Extension accepts JSON and base64 configurations.

  • One or more Secret queries (See query syntax below)

While it is possible to simply copy a Keeper Secrets Manager configuration into the pipeline, we recommend keeping the Secrets Manager configuration in an Azure Key Vault that is accessible to your Azure Pipeline. See Microsoft's documentation to learn more about Azure Key Vault.

Submit the form to add a task to your configuration automatically.

Manually add Task

To add a task manually to the pipeline configuration, follow this syntax:

- task: <Task Name>
  inputs:
    keepersecretconfig: <Secrets Manager Configuration>
    secrets: |
      <Secrets Queries>
- task: ksmazpipelinetask@1
  inputs:
    keepersecretconfig: $(secret_config)
    secrets: |
      6ya_fdc6XTsZ7i7x9Jcodg/field/password > pazzword
      6ya_fdc6XTsZ7i7x9Jcodg/field/login > LOGIN
      6ya_fdc6XTsZ7i7x9Jcodg/file/build-vsix.sh > file:/tmp/build-vsix.sh

Keeper Secret Queries

Queries for secrets in the Keeper Vault use the following syntax:

Get a Standard Field Value

Syntax

[UID]/field/[FIELD NAME] > [VARIABLE NAME]

Example

6ya_fdc6XTsZ7i7x9Jcodg/field/password > my_password

Get a Custom Field Value

Syntax

[UID]/custom_field/[FIELD NAME] > [VARIABLE NAME]

Example

6ya_fdc6XTsZ7i7x9Jcodg/custom_field/notes > MyNotes

Get a Two-Factor Code

Syntax

[UID]/field/oneTimeCode > [VARIABLE NAME]

Example

6ya_fdc6XTsZ7i7x9Jcodg/field/oneTimeCode > MyOneTimeCode

Get a File

Syntax

[UID]/file/[SECRET FILE NAME] > file:[OUTPUT FILE NAME]

Example

6ya_fdc6XTsZ7i7x9Jcodg/file/cert.pem > file:secret-cert.pem

Variable Types

When saving a secret from the Keeper vault as a variable on your Pipeline, there are a few options for how to set those variables, depending on your needs.

OUT

out (default) sets the secret to a variable which is accessible in any jobs in the pipeline. If you do not define a variable type, out will be used by default.

6ya_fdc6XTsZ7i7x9Jcodg/field/password > pazzword
6ya_fdc6XTsZ7i7x9Jcodg/field/password > out:my_password

VAR

var sets the secret to a local variable, usable within the same pipeline job.

6ya_fdc6XTsZ7i7x9Jcodg/field/password > var:my_password

FILE

file sets the contents to a file. Usually used to access certificates and other files from the Keeper Vault.

6ya_fdc6XTsZ7i7x9Jcodg/file/build-vsix.sh > file:/tmp/build-vsix.sh

ENVIRONMENT VARIABLE

env set the secret as an environment variable which the build machine can access.

To do this, you first need to set the secret to a pipeline variable, then set it as an environment variable in the bash task.

- task: ksmazpipelinetask@1
  name: getKeeperSecrets
  inputs:
    keepersecretconfig: $(sm-config)
    secrets: |
      6ya_fdc6XTsZ7i7x9Jcodg/field/password > var:var_password
      
- bash: |
        echo "Using the mapped env variable: $MY_MAPPED_ENV_VAR_PASSWORD"
    env:
        $MY_MAPPED_ENV_VAR_PASSWORD: $(var_password)

Example Usage

Get Secrets From Keeper

This example pipeline sets secrets from the Keeper Vault to variables and echoes them. Note that echoed passwords are masked.

trigger:
- master

pool:
  vmImage: ubuntu-latest

steps:

- task: ksmazpipelinetask@1
  name: setKsmSecretsStep
  inputs:
    keepersecretconfig: $(sm-config)
    secrets: |
      6ya_fdc6XTsZ7i7x4Jcodg/field/password > var:var_password
      6ya_fdc6XTsZ7i7x4Jcodg/field/password > out_password2
      6ya_fdc6XTsZ7i7x4Jcodg/field/password > out:out_password
      6ya_fdc6XTsZ7i7x4Jcodg/field/oneTimeCode > var:MyOneTimeCode
      6ya_fdc6XTsZ7i7x4Jcodg/file/build-vsix.sh > file:/tmp/build-vsix.sh

- bash: |
    echo "Using an input-macro works                : $(var_password)"
    echo "Using an output variable (default method) : $(setKsmSecretsStep.out_password2)"
    echo "Using an output variable                  : $(setKsmSecretsStep.out_password)"
    echo "Using an output variable for totp         : $(setKsmSecretsStep.out_password)"
    echo "Using the mapped env var                  : $(MyOneTimeCode)"
    echo "Check injected secret file                : $(file /tmp/build-vsix.sh)"
  env:
    MY_MAPPED_ENV_VAR_PASSWORD: $(var_password) # the recommended way to map to an env variable
  name: display_secret_values

Use Secrets in Multiple Jobs

This example gets passwords and files from Keeper, and utilizes those passwords and files in another job.

trigger:
- master

pool:
  vmImage: ubuntu-latest

jobs:
- job: ksmSecrets
  displayName: "Inject KSM Secrets"

  steps:

  - task: ksmazpipelinetask@1
    name: setKsmSecretsStep
    inputs:
      keepersecretconfig: $(sm-config)
      secrets: |
        6ya_fdc6XTsZ7i7x9Jcodg/field/password > var:var_password
        6ya_fdc6XTsZ7i7x9Jcodg/field/password > out:out_password
        6ya_fdc6XTsZ7i7x9Jcodg/field/password > out_password2
        6ya_fdc6XTsZ7i7x9Jcodg/file/mykey.pub > file:/tmp/public_key.pem
        6ya_fdc6XTsZ7i7x9Jcodg/file/mykey.pem > file:/tmp/private_key.pem

  - bash: |
      echo "Using an input-macro works                : $(var_password)"
      echo "Using an output variable (default method) : $(setKsmSecretsStep.out_password2)"
      echo "Using an output variable                  : $(setKsmSecretsStep.out_password)"
      echo "Using the mapped env var                  : $MY_MAPPED_ENV_VAR_PASSWORD"
      echo "Check injected secret file                : $(file /tmp/public_key.pem)"
    env:
      MY_MAPPED_ENV_VAR_PASSWORD: $(var_password) # the recommended way to map to an env variable
    name: display_secret_values

  - bash: |
      cat << EOF > decrypted.txt
      This is a decrypted message
      EOF
    name: create_text_file

  - bash: cat decrypted.txt
    name: view_decrpyted_content


  - bash: openssl rsautl -encrypt -inkey /tmp/public_key.pem -pubin -in decrypted.txt -out ecrypted.bin
    name: encrypte_file

  - bash: cat ecrypted.bin
    name: view_encrpyted_content

  - bash: openssl rsautl -decrypt -inkey /tmp/private_key.pem -in ecrypted.bin -out decrypted2.txt
    name: decrpyt_content

  - bash: cat decrypted2.txt
    name: view_decrpyted2_content


- job: encryptFileTest
  dependsOn: ksmSecrets
  variables:
    # map the output variable from A into this job
    # Note:
    #   that files can't be shared between jobs each agent can run only one job at a time
    #   one job is an independent running individual, the communication between different 
    #   jobs requires the use of "middleware", like variable, artifact and etc.
    pwdFromKsmSecrets: $[ dependencies.ksmSecrets.outputs['setKsmSecretsStep.out_password'] ]

  steps:
    - bash: |
        echo "password retrieved from job 'ksmSecrets', step 'pwdFromKsmSecrets', out variable 'setKsmSecretsStep.out_password':$(pwdFromKsmSecrets)"

Azure Key Vault Sync

Sync secrets from the Keeper Vault with Azure Key Vault

About

The Keeper Secrets Manager CLI tool sync command allows you to push secrets from the Keeper Vault to a target Azure Key Vault account, overwriting the existing values in the target location. This allows the Keeper Vault to be the single source of truth for any services or scripts in Azure which utilize the Key Vault.

Features

  • Use secrets from the Keeper Vault as the source of truth for Azure Key Vault

  • Seamlessly start using secrets from the Keeper Vault with your existing Azure scripts and services

Prerequisites

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An Azure account with Key Vault, and the ability to create security principals

Setup

1. Configure Keeper Secrets Manager CLI

You can skip this step if the KSM CLI is already configured on your machine.

To configure the KSM CLI tool, a profile needs to be created with the Keeper Secrets Manager One Time Access Token.

The simplest way to do this is to initialize the default profile with the following command:

ksm profile init <TOKEN>

For information on creating multiple profiles and other options, see the profile documentation

2. Set Azure Permissions

To use KSM sync with Azure, the Azure account needs to be configured to accept the connection. The Azure account with Key vault needs to enable a service principal with authorization to perform key operations in the Key Vault.

Follow the Microsoft guide for setting up a service principal: https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals

3. Create Azure Credentials Record

The KSM CLI needs the credentials for the Azure account to set secrets. These credentials are stored in a Keeper record which the CLI tool can access using Keeper Secrets Manager.

Record fields with the following labels are required on the credentials record:

"Azure Tenant ID" "Azure Client ID" "Azure Client Secret" "Azure Key Vault Name"

When retrieving the Client secret from Azure app registration, make sure to copy the Value (not Secret ID) into "Azure Client Secret" field.

(Method 1) Create an Azure Credentials Custom Record Type

A custom record type can be created with the required fields, which makes it easy and clean to create a record.

To create a custom record type, go to the "Custom Record Types" tab in the Keeper Vault and hit "Create Type". Create a new record type with hidden fields that have the correct field label, then click "Publish" to create the new record type.

Then simply create a new record of the Azure Credentials type and enter the details into the corresponding fields.

Make sure this new record is in a shared folder that is shared to your Secrets Manager application.

(Method 2) Add Custom Fields

To create a credentials record without creating a new record type, the required fields can be added as custom fields to a standard record.

Create a new record of any type, then add Custom Fields of the 'Hidden Field' type for each required Azure field. Click "Edit Label" to change the labels to the corresponding field name.

Any record type will work, but the "File Attachment" standard record type has no fields and will be cleaner looking when custom fields are added

Then fill in each custom field and hit "Save" to save the record.

4. Create Value Mappings

The KSM CLI sync command identifies which values to set using mappings that are defined on the command call. For each mapping passed to the command, a value with the given name will be populated with the given value from the Keeper Vault.

These mappings follow this format:

--map "VALUE KEY" "KEEPER NOTATION"

VALUE KEY is the key name that the value will be assigned in Azure Key Vault

KEEPER NOTATION is a Keeper notation query of a value from a keeper record to set to the key

Keeper notation is a query notation used by Keeper Secrets Manager to identify specific record values. The notation follows the general format of: UID/[field|custom_field]/fieldname for example: ae3d[...]d22e/field/password

See the Keeper Notation documentation for more information

Note that full record UIDs are not given in these examples

Full Mapping Example: --map "MySQL_PWD" "jd3[...]i-fd/field/password"

Multiple mappings can be added to a single sync command --map "MySQL_PWD" "jd3[...]i-fd/field/password" --map "MySQL_Login" "jd3[...]i-fd/field/login"

Ensure that the records referenced by the Keeper Notation queries are in a shared folder that is shared with your Secrets Manager application

KSM sync is now ready to run

Run Sync

To run the sync, use the KSM CLI sync command with the credentials record and value mapping

1. Construct the Command

Put together the KSM sync command with the Azure type. The format looks like the following:

ksm sync --type azure --credentials [UID] --map [...] --map [...]

2. Run a Dry-Run

The sync command supports running a dry-run which will identify all changes that will be made to your Azure Key Vault values without actually pushing the values or making changes. Use this to make sure your mapping queries are constructed properly.

ksm sync --type azure --credentials [UID] --map [...] --map [...] --dry-run

3. Run the Sync

When ready, run the sync command without the dry-run option. This will push values from your Keeper Vault to Azure Key Vault

TIP: you can use -m as short hand for --map

ksm sync --type azure --credentials [UID] -m [...] -m [...]

Azure Key Vault Encryption

Protect Secrets Manager connection details with Azure Key Vault Keys

Keeper Secrets Manager integrates with Azure Key Vault in order to provide encryption for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all your secret credentials.

Features

  • Encrypt and Decrypt your Keeper Secrets Manager configuration files with Azure Key Vault.

  • Protect against unauthorized access to your Secrets Manager connections.

  • Requires only minor changes to code for immediate protection. Works with all Keeper Secrets Manager SDK functionality.

  • supports RSA Asymmetric keys from Azure.

Prerequisites

  • Support the Java/Kotlin Secrets Manager SDK.

  • Requires Azure packages: azure-identity and azure-keyvault-keys.

  • Works with just RSA key types with WrapKey and UnWrapKey permissions.

  • Supports the JavaScript Secrets Manager SDK

  • Requires Azure packages @azure/identity , @azure/keyvault-keys

  • Works with just RSA key types with WrapKey and UnWrapKey permissions.

  • Supports the Python Secrets Manager SDK

  • Requires package azure-identity azure-keyvault-keys

  • Works with just RSA key types with WrapKey and UnWrapKey permissions.

  • Supports the .Net Secrets Manager SDK

  • Supports dotnet version net9.0

  • Requires Azure packages: Azure.Identity and Azure.Security.KeyVault.Keys

  • Works with just RSA key types with WrapKey and UnWrapKey permissions.

  • Supports the GoLang Secrets Manager SDK

  • Requires Azure packages: azcore , azidentity and azkeys.

  • Works with just RSA key types with WrapKey and UnWrapKey permissions.

Setup

1. Install Module

Setting up project using Gradle or Maven

Gradle

repositories {
  mavenCentral()
}

dependencies {
  implementation("com.keepersecurity.secrets-manager:azurekv:1.0.0")
  implementation("com.keepersecurity.secrets-manager:core:17.0.0")
  implementation("com.azure:azure-identity:1.15.0")
  implementation("com.azure:azure-security-keyvault-keys:4.9.2")
  implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
  implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
  implementation("com.google.code.gson:gson:2.12.1")
  implementation("org.slf4j:slf4j-api:1.7.32"){
        exclude("org.slf4j:slf4j-log4j12")
    }
  implementation("ch.qos.logback:logback-classic:1.2.6")
  implementation("ch.qos.logback:logback-core:1.2.6")
  implementation("org.bouncycastle:bc-fips:1.0.2.4")
}

Maven

<!-- KMS-core -->
 <dependency>
     <groupId>com.keepersecurity.secrets-manager</groupId>
     <artifactId>azurekv</artifactId>
     <version>1.0.0</version>
</dependency>
<dependency>
     <groupId>com.keepersecurity.secrets-manager</groupId>
     <artifactId>core</artifactId>
     <version>17.0.0</version>
 </dependency>

 <!-- Azure-identity -->
   <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-identity</artifactId>
       <version>1.15.0</version>
        <scope>compile</scope>
   </dependency>
  <!-- Azure-keyvault -->
   <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-security-keyvault-keys</artifactId>
       <version>4.9.2</version>
   </dependency>
      	
   <!--gson -->
   <dependency>
   	<groupId>com.google.code.gson</groupId>
   	<artifactId>gson</artifactId>
   	<version>2.12.1</version>
   </dependency>

   <!--jackson-core -->
   <dependency>
   	<groupId>com.fasterxml.jackson.core</groupId>
   	<artifactId>jackson-core</artifactId>
   	<version>2.18.2</version>
   </dependency>
   	
   <!--jackson-databind -->
   <dependency>
   	<groupId>com.fasterxml.jackson.core</groupId>
   	<artifactId>jackson-core</artifactId>
   	<version>2.18.2</version>
   </dependency>
   <!-- slf4j-api -->
	<dependency>
	   <groupId>org.slf4j</groupId>
	   <artifactId>slf4j-api</artifactId>
	   <version>1.7.32</version>
	   <scope>runtime</scope>
	</dependency>	
  <!-- logback-classic -->
   <dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.6</version>
	<scope>compile</scope>
  </dependency>
<!-- logback-core -->
   <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.6</version>
      <scope>compile</scope>
   </dependency>  	
   <!-- bc-fips -->
   <dependency>
   	<groupId>org.bouncycastle</groupId>
   	<artifactId>bc-fips</artifactId>
   	<version>1.0.2.4</version>
   </dependency>
   	

The Secrets Manager Azure Key Vault module can be installed using npm

npm install @keeper-security/secrets-manager-azure

The Secrets Manager Storage Azure module can be installed using pip

pip3 install keeper-secrets-manager-storage

The Secrets Manager KSM modules are located in the Keeper Secrets Manager storage module which can be installed using dotnet

dotnet add package Keeper.SecretsManager.AzureKeyVault

The Secrets Manager azure KSM module Integration can be installed using

go get github.com/keeper-security/secrets-manager-go/integrations/azure

2. Configure Azure Key Vault Connection

Ensure that you have an Azure Key Vault instance available, The following param needed to connect azure key vault AZURE_TENANT_ID: The Microsoft Entra tenant (directory) ID.

AZURE_CLIENT_ID: The client (application) ID of an App Registration in the tenant.

AZURE_CLIENT_SECRET: A client secret that was generated for the App Registration.

You will need an Azure App directory App to use the Azure Key Vault integration.

For more information on Azure App Directory App registration and Permissions see the Azure documentation:

https://learn.microsoft.com/en-us/azure/key-vault/general/authentication

3. Add Azure Key Vault Storage to Your Code

Once azure connection has been configured, You can fetch the Key to encrypt / decrypt KSM configurations using azure key and you need to tell the Secrets Manager SDK to utilize the key vault as storage.

Using Azure Key Vault Integration

Once setup, the Secrets Manager Azure Key Vault integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the Azure Keys in order to manage the encryption and decryption of the KSM configuration file. Using Specified Connection credentials

To do this, create AzureKeyValueStorage instance and use this in SecretManagerOptions constructor.

The AzureKeyValueStorage will require the name of the Secrets Manager configuration file with azure_key_id , azure_keyvault_URL and configuration.

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretmanager.azurekv.AzureKeyValueStorage;
import com.keepersecurity.secretmanager.azurekv.AzureSessionConfig;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;


class Test {
	public static void main(String args[]){
		String oneTimeToken = "[One_Time_Token]";
		String keyId = "https://<vault-name>.vault.azure.net/keys/<keyname>/<keyversion>";
		String configFileLocation="<KSM-client-config.json>";
		String azTenantId = "<azure-tenant-id>";
		String azClientId = "<azure-client-id>";
		String azClientSecret = "<azure-client-secret>";
		String keyVaultUrl = "https://<vault-name>.vault.azure.net/";
		Security.addProvider(new BouncyCastleFipsProvider());
		try{
			//set azure KV configuration, 
			AzureSessionConfig azConfig= new AzureSessionConfig(azTenantId, azClientId, azClientSecret, keyVaultUrl);
			//Get Storage 
			AzureKeyValueStorage azkvstorage =  AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
			initializeStorage(azkvstorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(azkvstorage);
			//getSecrets(options)
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

To do this, use AzureKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an Azure Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by Azure Key Vault.

 import { getSecrets, initializeStorage, localConfigStorage } from '@keeper-security/secrets-manager-core';
 import {AzureKeyValueStorage, AzureSessionConfig} from "@keeper/secrets-manager-azure";
 
     const getKeeperRecords = async () => {
        const tenant_id="<tenant_id>" 
        const client_id="<client_id>"
        const client_secret="<client-secret>"
        const azureSessionConfig = new AzureSessionConfig(tenant_id, client_id, client_secret)
        
        let config_path = "<path to ksm-client-config.json>"
        const logLevel = LoggerLogLevelOptions.info;
        // oneTimeToken is used only once to initialize the storage
        // after the first run, subsequent calls will use ksm-config.txt
        const oneTimeToken = "[One Time Token]";
        
        const keyId = 'https://<vault_name>.vault.azure.net/keys/<key_name>/<version>'
        const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig,logLevel).init();
        await initializeStorage(storage, oneTimeToken);
        
        const {records} = await getSecrets({storage: storage});
        console.log(records)
    }
    getKeeperRecords()

To do this, use AzureKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor as config along with a token.

The storage will require a Azure Key ID, as well as the location of the Secrets Manager configuration file which will be encrypted by Azure-KSM Integration and Azure session configuration as shown below.

from keeper_secrets_manager_storage.storage_azure_keyvault import AzureSessionConfig,AzureKeyValueStorage
from keeper_secrets_manager_core import SecretsManager

tenant_id = "<Tenant_ID>"
client_id = "<CLIENT_ID>"
client_secret = "<CLIENT_SECRET>"

azure_session_config = AzureSessionConfig(tenant_id, client_id, client_secret)
config_path = "<path_to_client_config_python.json>"

token="<One Time Token>"

key_id = "<key_id>"

azure_key_value_storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
    
secrets_manager = SecretsManager(token = token,config=azure_key_value_storage)
    
records  = secrets_manager.get_secrets()
    
for record in records:
    print(record)

To do this, use AzureKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an Azure Key ID, as well as the name of the Secrets Manager configuration file which will be encrypted by Azure Key Vault. Optionally AzureSessionConfig can be provided. If credentials are not provided the default credentials are used.

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OracleKeyManagement;
using SecretsManager;

public class Program
{
   private static async Task getOneIndividualSecret()
    {
        var tenant_id = "<TENANT_ID>";
        var client_secret = "<CLIENT_SECRET>";
        var client_id = "<CLIENT_ID>";
        var keyId = "<KEY_ID>";
        var path = "ksmConfigDotnet.json";
        var dotnet_access_token = "<ACCESS_TOKEN>";
        var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.SetMinimumLevel(LogLevel.Debug);
            builder.AddConsole();
        });
        var logger = loggerFactory.CreateLogger<AzureKeyValueStorage>();
        var azure_session_config = new AzureSessionConfig(tenant_id, client_id, client_secret);
        AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
        SecretsManagerClient.InitializeStorage(azure_storage, dotnet_access_token);
        
        var options = new SecretsManagerOptions(azure_storage);
                    var records_list = await SecretsManagerClient.GetSecrets(options);
        records_list.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
    }
	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}

To do this, use NewAzureKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The NewAzureKeyVaultStorage requires the following parameters to encrypt the KSM configuration using Azure Key Vault:

ksmConfigFileName : The file name of KSM configuration.

keyURL: Azure Key URL

package main

import (
	"encoding/json"
	"fmt"

	"github.com/keeper-security/secrets-manager-go/core"
	azurekv "github.com/keeper-security/secrets-manager-go/integrations/azure"
)

func main() {
	
	ksmConfigFile := ""
	oneTimeToken := "oneTimeToken"
	keyURL := "<Key URL>"   	}
	
	//Initialize the Azure Key Vault Storage
	cfg := azurekv.NewAzureKeyValueStorage(ksmConfigFileName, keyURL, &azurekv.AzureConfig{
		TenantID:     "<Azure Tenant ID>",
		ClientID:     "<Azure Client ID>",
		ClientSecret: "<Azure Client Secret>",
	})
	// create a new secrets manager client
	secrets_manager := core.NewSecretsManager(
		&core.ClientOptions{
			Config: cfg,
			Token:  oneTimeToken,
		},
	)
	// Fetch all the secrets from the vault
	secrets, err := secrets_manager.GetSecrets([]string{})
	if err != nil {
		// do something
		fmt.Printf("Error: %s\n", err)
	} else {
		for _, secret := range secrets {
			fmt.Printf("Recieved secret: %s\n", secret.Title())
		}
	}

}

Additional Options

Change Key

We can change key that is used for encrypting the KSM configuration, examples below show the code needed to use it

//The method changeKey(newKeyID) will be used to encrypt the KSM config file with new azure key. 
....
 String newKeyID = "https://<vault-name>.vault.azure.net/keys/<keyname>/<keyversion>";
 AzureKeyValueStorage azkvstorage =  AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
 boolean isChanged = azkvstorage.changeKey(newKeyID);	 // Change the key for encryption/decryption
....
// To change the Azure Key Vault key used for encryption, you can call the `changeKey` method on the `OciKeyValueStorage` instance.
.....
 const keyId = 'https://<vault_name>.vault.azure.net/keys/<key_name>/<version>'
 const keyId2 = "https://<vault_name>.vault.azure.net/keys/<key_name>/<version>"
 const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig).init();
 await storage.changeKey(keyId2);

.....
azure_key_value_storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
new_key_id = "<new key id>"
isChanged = azure_key_value_storage.change_key(new_key_id = new_key_id)
print("Key is changed " + isChanged)
// To change the Azure key used for encryption, you can call the `ChangeKeyAsync` method on the `AzureKeyValueStorage` instance.
 using Microsoft.Extensions.Logging;
 ....
     var keyId2 = "<KEY_ID_2>";
     var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddConsole();
            });
    var logger = loggerFactory.CreateLogger<AzureKeyValueStorage>();
    AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
    azure_storage.ChangeKeyAsync(keyId2).Wait();
 ....
	....	
		updatedConfig := &azurekv.AzureConfig{
			TenantID:     "<Updated Tenant ID>",
			ClientID:     "<Updated Client ID>",
			ClientSecret: "<Updated Client Secret>",
		}
		updatedKeyURL := "<Updated Key URL>"		
		// Changes the key
		// If you don't want to change Config, pass nil as a paramter
		isChanged, err := cfg.ChangeKey(updatedKeyURL, updatedConfig)
		if err != nil {
			fmt.Printf("Error while changing key: %v", err)
		} else {
			fmt.Printf("Key changed: %v\n", isChanged)
		}
		.....

Decrypt Config

We can decrypt the config if current implementation is to be migrated onto a different cloud or if you want your raw credentials back. The function accepts a boolean which when set to true will save the decrypted configuration to file and if it is false, will just return decrypted configuration. This function accepts a boolean, when set to true will save the decrypted configuration to file and when set to false will return decrypted configuration.

....
 AzureKeyValueStorage azkvstorage =  AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
 azkvstorage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
 //OR 
 azkvstorage.decryptConfig(true); // Set true as a parameter to extract plaintext and save config as a plaintext.
....
 //To decrypt the config file and save it again in plaintext, you can call the `DecryptConfigAsync` method on the `AzureKeyValueStorage` instance.
.... 
 const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig).init();
 const decryptedConfig = storage.DecryptConfigAsync(true).wait(); // return decrypted and Saves to file
  //OR
 const decryptedConfig = await storage.decryptConfig(false); // returns the decrypted config 
.... 
storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
storage.decrypt_config() #saved plain config to file
 # or
storage.decrypt_config(False)# returns config as return value, file will stay encrypted
//To decrypt the config file and save it again in plaintext, you can call the `DecryptConfigAsync` method on the `AzureKeyValueStorage` instance.
.... 
var keyId2 = "<KEY_ID_2>";
 AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
await azure_storage.DecryptConfigAsync(true); // return decrypted and Saves to file
//OR
await azure_storage.DecryptConfigAsync(false); // returns the decrypted config 
.... 
		.....
		configs := make(map[core.ConfigKey]interface{})
		plainText, err := cfg.DecryptConfig(true)
		if err != nil {
			// do something
			fmt.Printf("Error while decrypting config: %v", err)
		} else {
			if err := json.Unmarshal([]byte(plainText), &configs); err != nil {
				fmt.Printf("Error while unmarshalling: %v", err)
			}
			fmt.Printf("Decrypted data: %v\n", configs["clientId"])
		}
		.....

You're ready to use the KSM integration 👍

Check out the KSM SDKs documentation for more examples and functionality

Bitbucket Plugin

Keeper Secrets Manager integration into Bitbucket for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault within BitBucket Pipelines

  • Set secret credentials as build arguments or environment variables in BitBucket Pipeline scripts

  • Copy secure files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager BitBucket integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The BitBucket integration accepts JSON and Base64 format configurations

Setup

Getting a configuration

Using Keeper Commander, add a new client to an application and initialize the configuration to a Base64 string. This will be the long text hash that appears after the "Initialized Config:" label.

My Vault> sm client add --app MyApp --config-init b64

Successfully generated Client Device
====================================

Initialized Config: eyJob3N0bmFtZSI6ICJr....OUk1ZTV1V2toRucXRsaWxqUT0ifQ==
IP Lock: Enabled
Token Expires On: 2021-10-19 15:31:31
App Access Expires on: Never

That value can be added to your BitBucket Repository variables, under Repository settings menu, as a secure secret with the name KSM_CONFIG. This will allo the configuration to be available to the Keeper Secrets Manager pipe as a variable.

Adding to bitbucket-pipeline.yml

image: atlassian/default-image:2

pipelines:
  default:
    - step:
        name: 'Build My Stuff'
        script:
          - pipe: keepersecurity/keeper-secrets-manager-pipe:<tag>
            variables:
              KSM_CONFIG: "${KSM_CONFIG}"
              SECRETS: |
                1adh_WZxtbbHWqf6IALMVg/field/login > MY_LOGIN
                V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png > file:my.png
              SCRIPT_TEXT: |
                #!/usr/bin/env bash
                echo "My Login = \${MY_LOGIN}"
                ls my.png
              SHOW_OUTPUT: "True"
              SECRETS_FILE: "secret.env"
              SECRETS_FILE_TYPE: "export"
          - source secret.env

Pipe Integration

The name of the pipe integration is the following.

        script:
          - pipe: keepersecurity/keeper-secrets-manager-pipe:<tag>

The pipe requires you to choose a git tag for the version. The README.md will always have the latest tag in the YAML Definition.

Variables

Required

KSM_CONFIG - The Keeer Secrets Mananger pipe requires configuration information. This can be stored in the Repository variables and pulled into a variable using "${KSM_CONFIG}"

SECRETS - The secrets are a new line separted list of Keeper Notation and destinations. The notation and desitnation are separated by the '>' character.

Optional

SCRIPT_FILE - The script file is an application, or shell script, that you wish to run inside of the pipe. The script will be able to access the secrets.

SCRIPT_TEXT - The script text allows you to hardcode a script inside of the bitbucket-pipeline.yml. It will be used if a SCRIPT_FILE does not exist. If used, you will need to escape any shell related special characters.

SECRETS_FILE - If set, secrets that were to be place into environmental varaibles will also be placed into a file. The format of the file depends on the SECRET_FILE_TYPE.

SECRETS_FILE_TYPE - If a SECRET_FILE is used, this variable will determine it's format. Valid formats are 'json', 'export', 'setenv', and 'set'. The default is 'json'

SHOW_OUTPUT - A boolean flag to show the output from the SCRIPT_FILE or SCRIPT_TEXT. The REDACT variable will determine if you will be able to see your secrets in the ouput. By default, this flag is True.

SAVE_OUTPUT_FILE - If set, the output from the SCRIPT_FILE or SCRIPT_TEXT will be saved to a file.

REDACT - If True, any secret displayed from the SCRIPT_FILE or SCRIPT_TEXT will be replaced with '****'. By default, this flag is True. This does not redact output saved to a file.

REMOVE_FILES - If True, when the pipe exits it will delete any files it created. Those files will not be available outside of the pipe unless the value is set to False. By default, this is True.

CLEANUP_FILE - The name of a shell script that will remove any files created inside of the pipe. While the build workspace is removed when the build finishes, this shell file can be run to make sure the files are deleted. If not set, no clean up file will be created.

DEBUG - Enable debug message inside of the pipe. By default, this is False.

Retrieving Secrets

The SECRETS variable in the YAML contains a list of Keeper Notation and where the value should be stored. Secrets can be stored as an environmental variable or in a file.

The default destination for a variable is a environmental variable. The prefix env: can be added to the front of the environmental variable name, but is not required.

The environmental variable name must be a valid Unix environmental variable name

Saving secrets to an environment variable

The example below will take the login secret and place them into environmental variables. Both lines do the same, one without the env: prefix and one with.

        script:
          - pipe: keepersecuirty/keeper-secrets-manager-pipe:<tag>
            variables:
              KSM_CONFIG: "${KSM_CONFIG}"
              SECRETS: |
                1adh_WZxtbbHWqf6IALMVg/field/login > MY_LOGIN
                1adh_WZxtbbHWqf6IALMVg/field/login > env:SAME_LOGIN          

In the example, 1adh_WZxtbbHWqf6IALMVg is a record UID.

Saving secrets to a file

If the secret is binary data it is highly recommended not to store the secret in an environmental variable due to encoding issues. Use the file: destination instead.

        script:
          - pipe: keepersecurity/keeper-secrets-manager-pipe:<tag>
            variables:
              KSM_CONFIG: "${KSM_CONFIG}"
              SECRETS: |
                1adh_WZxtbbHWqf6IALMVg/file/server.xml > file:server.xml
                1adh_WZxtbbHWqf6IALMVg/file/domain.crt > file:config/path/domain.crt             

If the variable REMOVE_FILES is True, the file will be removed when the pipe exits. Set this variable to False if you wish to use the files outside of the pipe.

Examples

Example 1 - Docker Build

This example will create a Tomcat server Docker image that contains a custom server.xml config and keystore containing the SSL certs. The server.xml and keystore are stored in the Keeper Vault.

The first step is to create a repo in BitBucket, then add a Dockerfile. This Dockerfile will add two files created by the Keeper Secrets Manager pipe to an official Tomcat Docker image.

FROM tomcat:10-jdk16

ADD /server.xml /usr/local/tomcat/conf/server.xml
ADD /localhost-rsa.jks /usr/local/tomcat/conf/localhost-rsa.jks

# Expose port 8443 for SSL
EXPOSE 8443

Next a configuration is needed for the Keeper Secrets Manager pipe. This can be created using Keeper Commander and initializing the config as Base64.

My Vault> sm client add --app MyApp --config-init b64

Successfully generated Client Device
====================================

Initialized Config: eyJob3N0bmFtZSI6ICJr....OUk1ZTV1V2toRucXRsaWxqUT0ifQ==
IP Lock: Enabled
Token Expires On: 2021-10-19 15:31:31
App Access Expires on: Never

For more options creating a configuration, see the configuration documentation

The Initialized Config: Base64 string needs to be cut-n-pasted into your Repository variables. In this example the name of the variable is KSM_CONFIG. A private Docker Hub username and password are also added to the Repository variables.

Next a bitbucket-pipelines.yml file needs to be added to the repository.

image: atlassian/default-image:2

pipelines:
  default:
    - step:
        name: 'Build Custom Tomcat Server'
        script:
          - pipe: keepersecuirty/keeper-secrets-manager-pipe:<tag>
            variables:
              KSM_CONFIG: "${KSM_CONFIG}"
              SECRETS: |
                3GGclNXOoU0DwZwdn6iZmg/file/server.xml > file:server.xml
                3GGclNXOoU0DwZwdn6iZmg/file/localhost-rsa.jks > file:localhost-rsa.jks
              REMOVE_FILES: "False"
              CLEANUP_FILE: "ksm_cleanup.sh"
          - VERSION="1.$BITBUCKET_BUILD_NUMBER"
          - IMAGE="$DOCKERHUB_USERNAME/$BITBUCKET_REPO_SLUG"
          - docker login --username "$DOCKERHUB_USERNAME" --password "${DOCKERHUB_PASSWORD}"
          - docker image build -t ${IMAGE}:${VERSION} .
          - docker image tag ${IMAGE}:${VERSION} ${IMAGE}:latest
          - docker image push ${IMAGE}
          - git tag -a "${VERSION}" -m "Tagging for release ${VERSION}"
          - git push origin ${VERSION}
          - ./ksm_cleanup.sh
        services:
          - docker

The above is used to build a Docker image and push it to your Docker Hub account. The first step will use the Keeper Secrets Manager pipe to retrieve the two files and place them into the work directory.

The REMOVE_FILES variable is set to False since we don't want to delete them after the pipe has finished.

The CLEANUP_FILE variable is set to ksm_cleanup.sh which will create a script that will remove the two files when we are done.

When we build the Dockerfile, it will add the two files into the correct locations inside the image. When done it will push the image to the Docker Hub account.

The last part is running the ksm_cleanup.sh script that was set by the CLEANUP_FILE variable. This will make sure the two files we created are deleted. BitBucket Pipeline does delete the work space when it is done, however this guarantees the files are deleted.

Example 2 - Using Keeper Secrets Manager pipe with other pipes.

This example will retrieve secrets that are used as variables for another pipe. The other pipe is the AWS S3 Deploy pipe which will copy a local directory into a S3 bucket.

In the Keeper Vault, a record was created that contains our AWS credentials and information about the S3 bucket.

The first step is to create a repo in BitBucket, and then store the Keeper Secrets Manager pipe configuration in the Repository variables. This can be created using Keeper Commander and initializing the config as Base64.

My Vault> sm client add --app MyApp --config-init b64

Successfully generated Client Device
====================================

Initialized Config: eyJob3N0bmFtZSI6ICJr....OUk1ZTV1V2toRucXRsaWxqUT0ifQ==
IP Lock: Enabled
Token Expires On: 2021-10-19 15:31:31
App Access Expires on: Never

For more options creating a configuration, see the configuration documentation

The Initialized Config: Base64 string needs to be cut-n-pasted into your Repository variables. In this example the name of the variable is KSM_CONFIG.

Next a bitbucket-pipelines.yml file needs to be added to the repository.

image: atlassian/default-image:2

pipelines:
  default:
    - step:
        name: 'Copy Image To S3'
        script:
          - pipe: keepersecurity/keeper-secrets-manager-pipe:<tag>
            variables:
              KSM_CONFIG: "${KSM_CONFIG}"
              SECRETS: |
                IumwT1QYRr8TTCtY8rqzhw/custom_field/AWS_ACCESS_KEY_ID > AWS_ACCESS_KEY_ID
                IumwT1QYRr8TTCtY8rqzhw/custom_field/AWS_SECRET_ACCESS_KEY > AWS_SECRET_ACCESS_KEY
                IumwT1QYRr8TTCtY8rqzhw/custom_field/AWS_DEFAULT_REGION > AWS_DEFAULT_REGION
                IumwT1QYRr8TTCtY8rqzhw/custom_field/S3_BUCKET > S3_BUCKET
                V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png > file:to_s3/my_image.png
              SECRETS_FILE: "secrets.env"
              SECRETS_FILE_TYPE: "export"
          - source ./secrets.env
          - pipe: atlassian/aws-s3-deploy:1.1.0
            variables:
              AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
              AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"
              AWS_DEFAULT_REGION: "${AWS_DEFAULT_REGION}"
              S3_BUCKET: "${S3_BUCKET}"
              LOCAL_PATH: "to_s3"

The bitbucket-pipelines.yml contains the Keeper Secrets Manager pipe which will retrieve our AWS credential from a record and place them into environment variables. It will also get a PNG image and write it into a directory called to_s3. The pipe will create a secrets file called secrets.env.

The SECRETS_FILE_TYPE is export which will allow the contents to be sourced and the secret values placed into environment.

Next the secrets file is sourced. This allows other pipes, and applications, access to the secrets as environmental variables.

The last step is using the aws-s3-deploy pipe to copy the image to the S3 bucket. The variables for the aws-s3-deploy pipe are set using the environmental variables provided by the Keeper Secrets Manager pipe's secret file.

Docker Image

Using environmental variable substitution with containerized environments

Docker Secrets Management

Features

  • Pass secret credentials from the Keeper Vault to Docker images

  • Build Docker Images with secret credentials from the Keeper Vault using build arguments

  • Copy files from the Keeper vault into Docker containers

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Docker Image b Actions integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A One Time Access Token

  • The Keeper Secrets Manager (KSM) CLI Tool

    • See instructions on setting up the KSM CLI here

About

The Secrets Manager CLI can be used to pull secrets from a Docker image at runtime, or it can be used by building it into the docker image. Several use cases are described in this document.

Example 1: Build an Image with Secrets using BuildKit

Secrets from the Keeper Vault can be built into a Docker container using Docker BuildKit. As of Docker 18.09 or later, image building supports the ability to pass secrets in via a mounted file system. As a simple example demonstrating this capability, we will be creating a user account in the destination image with a username and password from Keeper Secrets Manager.

Step 1: Set Environmental Variables with Keeper notation for the secrets that are needed. For more notation examples click here.

export MY_UID="SOAsfj_lIg0VenDr83gjDw"
export MY_USER="keeper://${MY_UID}/field/login"
export MY_PASS="keeper://${MY_UID}/field/password"

Step 2: Using the ksm exec command, the Docker build is created with the 2 secrets (login and password). The --secret parameters will pull values from the environmental variables that have been substituted with Keeper secrets.

DOCKER_BUILDKIT=1 ksm exec -- \
    docker build \
    --secret id=my_user,env=MY_USER \
    --secret id=my_password,env=MY_PASS \
   -t my_image .

Step 3: In the dockerfile, we will create a linux user account using useradd and then set the password with chpasswd. The Docker file is below:

FROM my_base_image

RUN --mount=type=secret,id=my_user,dst=/my_secrets/my_user \
    --mount=type=secret,id=my_password,dst=/my_secrets/my_password \
      useradd "$(cat /my_secrets/my_user)" && \
      echo "$(cat /my_secrets/my_user)":"$(cat /my_secrets/my_password)" | chpasswd

In this example, each secret is mounted as a file. The 'dst' value specifies where you want to temporarily store the secret. Once the RUN command is finished, the temporary file will be removed and unmounted. You can either pass the file name as an argument or in this case we are using cat $(/path/to/secret) to read the file contents into a variable.

Example 2: Build an Image with Secrets using Build Arguments

Similar to example 1, you can pass in secrets via the --build-arg. This example will also demonstrate the ability of using secrets in a Docker build process.

Step 1: Set Environmental Variables with Keeper notation for the secrets that are needed. For more notation examples click here.

export MY_UID="SOAsfj_lIg0VenDr83gjDw"
export MY_USER="keeper://${MY_UID}/field/login"
export MY_PASS="keeper://${MY_UID}/field/password"

Step 2: Using the ksm exec command, the Docker build is created with the 2 secrets (login and password). The flag --inline processes the replacement of secrets. For example:

ksm exec --inline -- \
   docker build \
     --build-arg "BUILD_MY_USER=${MY_USER}" \
     --build-arg "BUILD_MY_PASSWORD=${MY_PASSWORD}" \
     -t my_image .

Step 3: In the dockerfile, we will create a linux user account using useradd and then set the password with chpasswd. The Docker file is below:

FROM my_base_image
​ARG BUILD_MY_USER
ARG BUILD_MY_PASSWORD
 
RUN useradd "$(printenv --null BUILD_MY_USER)" && \
  echo "$(printenv --null BUILD_MY_USER)":"$(printenv --null BUILD_MY_PASSWORD)" | chpasswd

​To prevent secrets being sent to stdout from the printenv command, use the --null option to remove the line feed.

Example 3: Using docker-compose to Build an Image with Secrets

In this example, we will use docker-compose to build an image. Docker-compose cannot populate build args from environment variables. To replace notation with secret values, the build args need to be set via the command line. Since the notation will be on the command line, the --inline replacement flag needs to be set.

Step 1: Create a simple docker-compose.yaml file:

---
version: "3"
services:
  my_app:
    build:
      content: "."

Step 2: Using the ksm exec command, the Docker build is created with the 2 secrets (login and password). The flag --inline processes the replacement of secrets. For example:

ksm exec --inline -- \
   docker-compose build \
     --build-arg "BUILD_MY_USER=${MY_USER}" \
     --build-arg "BUILD_MY_PASSWORD=${MY_PASSWORD}" \
     -t my_image .

Step 3: In the dockerfile, we will create a linux user account using useradd and then set the password with chpasswd. The Docker file is below:

FROM my_base_image
​ARG BUILD_MY_USER
ARG BUILD_MY_PASSWORD
 
RUN useradd "$(printenv --null BUILD_MY_USER)" && \
  echo "$(printenv --null BUILD_MY_USER)":"$(printenv --null BUILD_MY_PASSWORD)" | chpasswd

​To prevent secrets being sent to stdout from the printenv command, use the --null option to remove the line feed.

Example 4: Copy files from vault to Docker Image

In this real world example, we copy an SSL certificate and passphrase from the Keeper Vault to a Tomcat container.

By default, the official Tomcat docker contains a default server configuration that does not have SSL enabled. We are going build a custom image that installs our server.xml, copies over the keystore file, and enables SSL. The server.xml file also contains the secret passphrase for the keystore file.

Step 1: Create a Keeper Secret Record

In the Keeper Vault, create a secret record that contains 2 file attachments: server.xml and localhost-rsa.jks as seen below:

Create Record with Secret File Attachments

Make note of the Record UID in the information dialog which will be used in the dockerfile. Click the Record UID to copy to your clipboard.

Copy the Record UID

Step 2: Create the dockerfile

The below dockerfile example copies the server.xml and keystore files from the vault into the Tomcat folder.

FROM tomcat:10-jdk16
​
ARG BUILD_KSM_INI_CONFIG
ARG BUILD_KSM_SERVER_UID
    
# The names of our files in our secret record
ARG BUILD_SERVER_CONFIG="server.xml"
ARG BUILD_KEYSTORE="localhost-rsa.jks"
  
# Temporarily install Python3
RUN apt-get update -y && \
    apt-get install -y \
    python3 \
    python3-pip \
    python3-venv
​
# Install modules in a known place so we can remove them later.
ENV VIRTUAL_ENV /venv
RUN python3 -m pip install --upgrade pip && \
    python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
​
# Upgrade pip since the distro's python might be old enough that it doesn't like to install newer modules.
RUN pip3 install --upgrade pip
RUN pip3 install keeper_secrets_manager_cli
​
RUN echo ${BUILD_KSM_INI_CONFIG}
​
# Import the KSM Client Device configuration, decode it, and store it a place where ksm can find it.
RUN ksm profile import $(printenv --null BUILD_KSM_INI_CONFIG)
​
# Download the server.xml and keystore into the Tomcat conf directory
RUN ksm secret download -u ${BUILD_KSM_SERVER_UID} --name ${BUILD_SERVER_CONFIG} --file-output /usr/local/tomcat/conf/server.xml
RUN ksm secret download -u ${BUILD_KSM_SERVER_UID} --name ${BUILD_KEYSTORE} --file-output /usr/local/tomcat/conf/localhost-rsa.jks
​
# We no longer need ksm. Remove it, python, and Debian apt to make a smaller Docker image.
RUN rm -rf /venv keeper.ini
RUN apt-get purge -y \
    python3 \
    python3-pip \
    python3-venv && \
    apt-get clean autoclean && \
    apt-get autoremove -y && \
    rm -rf /var/lib/{apt,dpkg,cache,log}/
​
# Expose port 8443 for SSL
EXPOSE 8443

Note that in this use case, ksm is no longer needed after the build, so it is deleted.

Step 3: Create a shell script to execute the docker build

To execute the docker build the below script will pass in the Secrets Manager device configuration and Record UID that contains the secret files.

#!/bin/sh

# Export the KSM profile as a string
export CF=$(ksm profile export _default)

# Execute the docker build, passing in the Record UID
# that contains the secret files
docker build \
  --build-arg "BUILD_KSM_INI_CONFIG=${CF}" \
  --build-arg "BUILD_KSM_SERVER_UID=LdRkidFLPF7vDaogwJ7etQ" \
  -t ksm_tomcat .

When the docker image is built, it will be fully configured with SSL, keystore file and passphrase that are managed by the Keeper Vault. 😃😃😃

Integration with Docker Compose

Keeper Secrets Manager supports direct integration with Docker Compose using the KSM Writer Docker image.

Learn more about the KSM Writer Docker image here.

Contribute to the Docker Image Examples

If you have some great examples to contribute to this page, please ping us on Slack or email sm@keepersecurity.com.

Docker Runtime

Retrieve secrets from Keeper Secrets Manager at Docker runtime

Features

  • Dynamically retrieve secrets from the Keeper Vault when Docker containers execute

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Docker Runtime integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A One Time Access Token

  • The Keeper Secrets Manager (KSM) CLI Tool

    • See instructions on setting up the KSM CLI here

About

Keeper Secrets Manager integrates with the Docker Runtime so that you can dynamically retrieve a secret from the vault when the container executes.

The ksm command is used to set environment variables when the container is started instead of hard-coding them into a deployment script. A real world example of this implementation is demonstrated below.

Example: Provision MySQL network user account

The official MySQL docker allows a user to set the MySQL root password and create a network accessible user via environment variables. The MySQL instance is then provisioned when a container is run.

The official MySQL dockerfile is below:

FROM debian:buster-slim
	
...
... INSTALL MySQL 8.0 SERVER
...
	
ENTRYPOINT ["docker-entrypoint.sh"]
​
EXPOSE 3306 33060
CMD ["mysqld"]

In the standard implementation, the ENTRYPOINT does the provisioning of the container and will use environmental variables that are passed in to set up MYSQL. The environmental variables referenced are the following:

  • MYSQL_ROOT_PASSWORD

  • MYSQL_USER

  • MYSQL_PASSWORD

  • MYSQL_DATABASE

The below steps will show how to initialize the MySQL database with secrets that are stored in the Keeper Vault.

Step 1: Create 2 Vault Records with Secrets

Create two records in the Vault that are managed by the Secrets Manager application. One record contains the root password. The other record contains the regular user, password and database values.

Root MySQL DB
User MySQL DB

Make sure to copy the Record UID that appears in the vault records. These are used in Step 3 below when referencing the vault secrets.

Capture Record UID for Root Record

Capture Record UID for User Record

Step 2: Create dockerfile that builds on the default MySQL dockerfile

We'll create a dockerfile that installs Keeper Secrets Manager CLI (ksm) and then wraps the ENTRYPOINT with ksm exec

In the below dockerfile, the 4 environment variables are replaced using Keeper Notation. We are also passing in the Secrets Manager profile that points to the vault where the secrets are stored.

FROM mysql:debian

ARG BUILD_KSM_INI_CONFIG
ARG BUILD_ROOT_UID
ARG BUILD_USER_UID

RUN apt-get update && \
  apt-get install -y python3 python3-pip python3-venv && \
  apt-get clean

# Avoid system installed modules that might interfer.
ENV VIRTUAL_ENV /venv
RUN python3 -m pip install --upgrade pip && \
  	python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

# Upgrade pip since the distro's Python might be old enough that it doesn't like to install newer modules.
RUN pip3 install --upgrade pip

# Install Keeper Secrets Manager CLI
RUN pip3 install keeper-secrets-manager-cli

# Import our configuration, decode it, and store it a place where ksm can find it.
RUN ksm profile import $(printenv --null BUILD_KSM_INI_CONFIG)

ENV MYSQL_ROOT_PASSWORD keeper://${BUILD_ROOT_UID}/field/password
ENV MYSQL_USER          keeper://${BUILD_USER_UID}/field/login
ENV MYSQL_PASSWORD      keeper://${BUILD_USER_UID}/field/password
ENV MYSQL_DATABASE      keeper://${BUILD_USER_UID}/custom_field/database
​
ENTRYPOINT ["ksm", "exec", "--", "docker-entrypoint.sh"]

​Step 3: Create a shell script to execute the docker build

To execute the docker build, the below script will pass in the Secrets Manager device configuration, root user Record UID and network user Record UID from the vault that contains the secrets.

#!/bin/sh
​
​export CF=$(ksm profile export)

docker build \
  --build-arg "BUILD_KSM_INI_CONFIG=${CF}" \
  --build-arg "BUILD_ROOT_UID=DvpMcO4xV5nZF6jqLGF1fQ" \
  --build-arg "BUILD_USER_UID=VNxZvvNAZ8j2mL4WIjEzjg" \
  -t mysql_custom \
  .
  

Example: Using KSM CLI Docker Image

The KSM CLI Docker includes a volume mount to both GLIBC (most Linux distributions) and MUSL (Alpine Linux) CLI binaries. The volume is /cli. This directory can be mounted into another container using the volumes_from in docker-compose or -v from command line docker. The ksm executables exists in directory based on the version of C library your Linux distribution is using.

  • /cli/glibc/ksm - For standard GLIBC distributions like Ubuntu, Debian, Fedora, and CentOS.

  • /cli/musl/ksm - For Alpine Linux.

For example, the following is simple framework showing how to access the CLI binary.

---
version: "2"
services:
  init:
    image: keeper/keeper-secrets-manager-cli:latest
  main:
    image: ubuntu:latest
    volumes_from:
      - init:ro
    command: [ '/cli/glibc/ksm', 'exec', 'printenv', 'MY_LOGIN' ]
    environment:
      KSM_CONFIG: ewog ... M09IemdQMnc9Igp9
      MY_LOGIN: keeper://bf18xLR3aVut5eYy7oIZZZ/field/login
      LC_ALL: C.UTF-8
      LANG: C.UTF-8
    depends_on:
      init:
        condition: service_completed_successfully

The init service will load the CLI docker. The container will start, display a CLI splash screen, and then will exit. Even though the container has stopped, the /cli volume is still accessible from other containers.

The main service will mount the CLI docker's volume under the directory /cli using volumes_from. The command is overridden to run the GLIBC version of the KSM CLI. The command is using the exec function of the CLI. That will replace environment variables environment variable, that use the Keeper Notation, with a secret value. The exec command, of the CLI, is running the printenv application. That will print the environment variable, MY_LOGIN, that has been set to Keeper Notation, and has had its value replaced with a secret by the exec command.

$ example : docker-compose up
[+] Running 2/0
 ⠿ Container example-init-1  Created                                                                                                                      0.0s
 ⠿ Container example-main-1  Recreated                                                                                                                    0.1s
Attaching to example-init-1, example-main-1
example-init-1  |
example-init-1  | ██╗  ██╗███████╗███╗   ███╗     ██████╗██╗     ██╗
example-init-1  | ██║ ██╔╝██╔════╝████╗ ████║    ██╔════╝██║     ██║
example-init-1  | █████╔╝ ███████╗██╔████╔██║    ██║     ██║     ██║
example-init-1  | ██╔═██╗ ╚════██║██║╚██╔╝██║    ██║     ██║     ██║
example-init-1  | ██║  ██╗███████║██║ ╚═╝ ██║    ╚██████╗███████╗██║
example-init-1  | ╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝     ╚═════╝╚══════╝╚═╝
example-init-1  |
example-init-1  | Current Version: 1.0.13
example-init-1  |
example-init-1  | Running in shell mode. Type 'quit' to exit.
example-init-1  |
example-init-1 exited with code 0
example-main-1  | john.smith@localhost
example-main-1 exited with code 0

Example: Using KSM CLI Docker With Other Vendor Docker Images

Similar to the examples above, the KSM CLI docker can be used to override the entrypoint and command for another vendor's Docker image without creating a custom Docker image.

This example, combines the first two examples.

For this example, it will be assumed the Docker image is being severed by the Docker Hub repository and the images' Dockerfile is stored on GitHub.

Operating System Distribution

The first step is to determine what operating system distribution the vendor's Docker image is built upon. Often this can be determined by the tag name. For example, if the name has "alpine" in the image tag name, you'll know it's the Alpine Linux distribution.

If the image tag name does not indicate the distribution, then on the Docker Hub web page for the image, click on the tag name in the "Supported tags" section. This will display the content of the Dockerfile. The FROM statement will indicate the distribution the vendor has built their image upon. If it is not apparent from the FROM statement, you man check the Dockerfile of the FROM image due to inheritance.

MySQL 8.0.31 doesn't indicate the operating system distribution in the tag name. On the MySQL Docker Hub page, the 8.0.31 tag links to their GitHub repo. From the Dockerfile we can see the distribution is Oracle Linux.

The purpose of checking the distribution is to determine what version of the libc library is being used. Most distributions use GLIBC but some, mainly Alpine Linux, uses MUSL. This is needed to select the correct binary from the KSM CLI Docker image. If you select the wrong one, you will get an error like exec /cli/musl/ksm: no such file or directory or exec /cli/glibc/ksm: no such file or directory. For our example, Oracle Linux is a GLIBC distribution.

Entrypoint and Command

The next step is to determine the vendor's Docker image ENTRYPOINT and CMD. The Dockerfile will list the ENTRYPOINT and/or CMD.

From the MySQL Dockerfile, the ENTRYPOINT is ["docker-entrypoint.sh"] and the CMD is ["mysqld"]. This means the ENTRYPOINT will be prepended to the CMD, so when the container is started docker-entrypoint.sh mysqld will be executed.

docker-compose.yml

The docker-compose uses two services.

The init service loads the keeper/keeper-secrets-manager-cli Docker image volumes. This image image will start and exit, however the volumes will still be accessible after it exits.

The main service will run after the init service. This is done by using the docker-composes depends_on directive. This service contains environment variables, with notation, that will be replaced by the KSM CLI exec command and also includes the Base64 encoded configuration needed by the KSM CLI. The MYSQL_ environmental variables are used by the MySQL Docker image to provision the database.

The main services also will mount the volumes from the init service using the volumes_from. The KSM CLI Docker image defined that volumes are exported, and where they are mounted in the main service container. The binaries are mounted in /cli, followed by the libc version, and the ksm binary name.

version: '3.0'
services:
  init:
    image: keeper/keeper-secrets-manager-cli:latest
  main:
    image: mysql:8.0
    environment:
      KSM_CONFIG: "ewog .... RQ3pQMnc9Igp9"
      MYSQL_USER: "keeper://KOJLz4Wzbqfi9xUO-VMViA/field/login"
      MYSQL_PASSWORD: "keeper://KOJLz4Wzbqfi9xUO-VMViA/field/password"
      MYSQL_ROOT_PASSWORD: "keeper://KOJLz4Wzbqfi9xUO-VMViA/custom_field/Root Password"
      MYSQL_DATABASE: "keeper://KOJLz4Wzbqfi9xUO-VMViA/custom_field/Database"
    depends_on:
      init:
        condition: service_completed_successfully
    entrypoint: ["/cli/glibc/ksm", "exec", "docker-entrypoint.sh"]
    command: ["mysqld"]
    ports:
      - "3306:3306"
    volumes_from:
      - init:ro

Since the MySQL image uses the Oracle distribution, a GLIBC distribution, the main service will use the /cli/glibc/ksm binary.

The main service will override the ENTRYPOINT and CMD of the MySQL image. This is done using entrypoint and command. The entrypoint will use the KSM CLI exec command to run the original ENTRYPOINT docker-entrypoint.sh. The command is the same, however it needs to be set in the docker-compose.yml else the service will just exit.

Based on the Docker image you are using, you may need override either ENTRYPOINT or CMD, or both.

Results

When the services are brought up. The init service will run first and then exit with a code 0, which means it exited successfully execute. Then the main services will start up, execute the KSM CLI exec command and run docker-entrypoint.sh with mysqld. At this point the environmental variable have been replaced with secrets, MySQL has been provisioned, and mysqld is running.

$ my_mysql : docker-compose up
[+] Running 3/3
 ⠿ Network my_mysql_default   Created                                                                                                          0.0s
 ⠿ Container my_mysql-init-1  Created                                                                                                          0.1s
 ⠿ Container my_mysql-main-1  Created                                                                                                          0.0s
Attaching to my_mysql-init-1, my_mysql-main-1
my_mysql-init-1  |
my_mysql-init-1  | ██╗  ██╗███████╗███╗   ███╗     ██████╗██╗     ██╗
my_mysql-init-1  | ██║ ██╔╝██╔════╝████╗ ████║    ██╔════╝██║     ██║
my_mysql-init-1  | █████╔╝ ███████╗██╔████╔██║    ██║     ██║     ██║
my_mysql-init-1  | ██╔═██╗ ╚════██║██║╚██╔╝██║    ██║     ██║     ██║
my_mysql-init-1  | ██║  ██╗███████║██║ ╚═╝ ██║    ╚██████╗███████╗██║
my_mysql-init-1  | ╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝     ╚═════╝╚══════╝╚═╝
my_mysql-init-1  |
my_mysql-init-1  | Current Version: 1.0.14
my_mysql-init-1  |
my_mysql-init-1  | Running in shell mode. Type 'quit' to exit.
my_mysql-init-1  |
my_mysql-init-1 exited with code 0
my_mysql-main-1  | 2022-10-31 21:35:26+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
my_mysql-main-1  | 2022-10-31 21:35:26+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
my_mysql-main-1  | 2022-10-31 21:35:26+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
my_mysql-main-1  | 2022-10-31 21:35:26+00:00 [Note] [Entrypoint]: Initializing database files
my_mysql-main-1  | 2022-10-31T21:35:26.830527Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
my_mysql-main-1  | 2022-10-31T21:35:26.830594Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.31) initializing of server in progress as process 83
...
my_mysql-main-1  | 2022-10-31T21:35:35.611063Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.31'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
my_mysql-main-1  | 2022-10-31T21:35:35.611015Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock

Contribute to the Docker Runtime Examples

If you have some great examples to contribute to this page, please ping us on Slack or email sm@keepersecurity.com.

Docker Writer Image

A general purpose docker image to retrieve secrets.

Overview

The Docker Writer Image for KSM is an image that can download secret files and also generate a file containing secrets.

The image can be pulled with the following command:

$ docker pull keeper/keeper-secrets-manager-writer

When run, its parameters are passed in via environmental variables.

$ docker run \
    -v $PWD:/wd --workdir /wd \
    -e "KSM_CONFIG=BASE64 CONFIG" \
    -e "SECRETS=JfXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt"
    keeper/keeper-secrets-manager-writer

The writer is used to copy files from the vault and to create files containing secrets. Due to writing information to disk, there is always risk of exposure. An alternative is the keeper/keeper-secrets-manager-cli image and the exec command.

Parameters

The parameters are handled by passing environment variables into the container.

Parameter
Description

KSM_CONFIG

A base64 encode configuration file.

SECRETS

A line-feed separated list of Keeper notation and destinations.

SECRETS_FILE

A filename to write the non-file destination secrets.

SECRETS_FILE_TYPE

The format of the secrets file. Valid format are export, setenv, set, and JSON. JSON is the default.

CLEANUP_FILE

If set, all files created will be added to the shell file to be removed when executed. This file can be executed to remove the files created.

Secrets List

The SECRETS are a list of Keeper Notation and destinations. The values are separated by line feeds. For example:

fXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt
cl9a9k0DWP-Iy227rBo5gQ/field/login > MY_LOGIN
gpsBL343CVYMFgOKZ-L2hQ/custom_field/Ip Address > IP_ADDR

Each line is "Keeper Notation > destination". The destination can be either an environmental variable/JSON key or a file path and name. If a file, the path is prefixed with the text file:. It is recommended not to place binary data into an environmental variable due to unknown string encoding.

Secret File Type

The secrets file contains the values of the environmental variable SECRETS. The format of the file is based on the value of SECRETS_FILE_TYPE. The type can be the following values:

  • json - Values stored in a JSON format.

  • export - Values stored as export commands commonly used with a BASH shell.

  • setenv - Values stored as setenv commands commonly used with C shell.

  • set - Values stored as set commands commonly used with C shell.

The types related to a shell can be sourced to place the secrets into the environment.

Examples

The Docker Writer Image for KSM can be used for many applications. Here are some examples.

Kubernetes

The writer image is best used in an Init Container.

 initContainers:
    - name: my_app
      image: keeper/keeper-secrets-manager-writer:latest
      env:
        - name: SECRETS
          value: |
            qCAw9dMQgr3Hs7EdfFpfkA/field/password > my_password
            qCAw9dMQgr3Hs7EdfFpfkA/file/exmaple.crt > file:/etc/keys/example.crt
            qCAw9dMQgr3Hs7EdfFpfkA/file/exmaple.key > file:/etc/keys/example.key

In this container, the writer image is used to save a file and create a secrets file that the main container can access. This can be done by mounting a volume, writing the files, and then having the main container mount the same value. The pod's emptyDir is a good choice.

Docker Compose

By using the depends_on options in the main service, the Docker Writer Image for KSM can be used in the initialization service. In the example below, the Docker Writer pulls secrets from the vault and shares them on a volume mount to the main image.

---
version: "2"
services:
  init:
    image: keeper/keeper-secrets-manager-writer:latest
    environment:
      KSM_CONFIG: R2VwWTVDS ... dmVyUHVibGljS2V5SWQiOiAiMTAiCn0=
      SECRETS: |
        qCAw9dMQgr3Hs7EdfFpfkA/field/password > file:/etc/keys/global.pass
        qCAw9dMQgr3Hs7EdfFpfkA/file/myserver.crt > file:/etc/keys/myserver.crt
        qCAw9dMQgr3Hs7EdfFpfkA/file/myserver.key > file:/etc/keys/myserver.key
    volumes:
      - keys-volume:/etc/keys
  main:
    image: nginx
    restart: always
    volumes:
     - ./config:/etc/nginx/conf.d
     - keys-volume:/etc/keys
    ports:
     - "80:80"
     - "443:443"
    environment:
     - NGINX_HOST=example.com
    depends_on:
      init:
        condition: service_completed_successfully
volumes:
  keys-volume:

Normally services start in parallel, however by using the depends_on option the service startup can be controlled. In the above, the main service depends on the init service.

The init service will start, retrieve and save the files into the keys-volume, then exit. By using the condition service_completed_successfully, when the init service successfully exits, it will start the main service. The main service will also mount the keys-volume and use the stored keys.

Docker Command Line

The writer image can be executed in the command line by using docker run.

docker run \
    -v $PWD:/wd --workdir /wd \
    -e "KSM_CONIFG=BASE64 CONFIG" \
    -e "SECRETS=JfXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt"
    keeper/keeper-secrets-manager-writer

If SECRETS has multiple secrets, the line-feed character (\n) is hard to represent. The solution is to surround the --env,-e value with $". For example

-e $'SECRETS=V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png > file:my.png\nIumwT1QYRr8TTCtY8rqzhw/custom_field/S3_BUCKET > s3'

Between file:my.png and the next record UID, there is a '\n'. If you don't wrap the entire value with $'' the my.png file name will include the escape line feed and the next record UID.

Entrust HSM Encryption

Protect Secrets Manager connection details locally with Entrust HSM

Keeper Secrets Manager integrates with Entrust HSM in order to provide encryption for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all you secret credentials.

Features

  • Encrypt and Decrypt your KSM configuration files with Entrust HSM

  • Protect against unauthorized access to your Secrets Manager connections

  • Requires only minor change to code for immediate protection. Works with all KSM Python SDK functionality

Prerequisites

  • Supports the Python Secrets Manager SDK

  • The Python module needs to be built as a nShield native application

    • Using Python (v3.8.5) and nfpython modules from SDK ISO image from Entrust nShield software (Security World 12.80 or later)

  • Virtualenv is recommended

Setup

1. Create and Configure Virtualenv

This step is optional, but recommended for development

Create a virtualenv environment to work in

/opt/nfast/python3/bin/python3 -m venv --copies venv

Activate the virtualenv environment before starting development

. venv/bin/activate

Create a virtualenv environment to work in

c:\Program Files\nCipher\nfast\python3\python --copies -m venv venv

Activate the virtualenv environment before starting development

venv\Scripts\activate.ps1

2. Install KSM Storage and nfpython Modules

The Secrets Manager HSM modules are located in the Keeper Secrets Manager storage module which can be installed using pip

pip3 install keeper-secrets-manager-storage

The nfpython package also needs to be installed in order to utilize the Entrust HSM. This package is installed as part of the nShield package with your Entrust installation.

In Linux:

pip install /opt/nfast/python3/additional-packages/nfpython*.whl 

In Windows:

pip install c:\Program Files\nCipher\nfast\python3\additional-packages\nfpython*.whl

3. Add Entrust HSM Storage to Your Code

Use the HsmNfastKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The HsmNfastKeyValueStorage requires the method and identity ("simple" and "ksmkey" respectively in this example).

entrust_hsm_example.py
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_hsm.storage_hsm_nfast import HsmNfastKeyValueStorage

config=HsmNfastKeyValueStorage('simple', 'ksmkey', 'client-config.json')

secrets_manager = SecretsManager(config=config, verify_ssl_certs=True)

all_records = secrets_manager.get_secrets()

You're all set and ready to use Secrets Manager with Entrust NShield HSM

Using Secrets Manager with Entrust HSM

Once setup, the Secrets Manager Entrust integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the nShield HSM in order to manage the decryption of the configuration file when run.

Check out the KSM SDKs documentation for more examples and functionality

Create an Encryption Key for Testing

In order to test encryption with the Entrust nShield HSM, use the following command:

Replace "ksmkey" in these examples with the identity in your HSM.

in Linux:

opt/nfast/bin/generatekey -b simple protect=module type=AES size=256 ident=ksmkey

in Windows:

c:\Program Files\nShield\nfast\bin\generatekey -b simple protect=module type=AES size=256 ident=ksmkey

Git - Sign Commits with SSH

Sign your git commits using an SSH key stored in your Keeper Vault

About

Signing your git commits is important. It verifies authorship, ensures the integrity of committed content, prevents identity spoofing, and establishes non-repudiation. Using a cryptographic signature with your private key demonstrates a commitment to the authenticity and security of your contributions, building trust among collaborators and protecting the repository from potential tampering and malicious code.

This integration allows developers to sign git commits with an SSH key protected in your Keeper Vault (via Keeper Secrets Manager).

Download the latest git-ssh-sign binaries

Features

  • Signs git commits using an SSH key stored in Keeper Vault.

  • Removes the need for SSH keys on disk for secure DevOps workflows.

  • Works on Windows, MacOS, and Linux.

  • Source code at https://github.com/Keeper-Security/git-ssh-sign

Prerequisites

In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with SSH key(s) shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • This integration only accepts JSON format configurations

  • Git installed with a minimum version of 2.34.0

Setup

1. Secrets Manager Configuration

  • Login to the Keeper Web Vault or Desktop App

  • Create a shared folder (e.g. "Git SSH Keys")

  • Add a SSH Key record to the shared folder

  • Generate

In order to fetch the SSH key from your vault, this integration uses the zero-knowledge Keeper Secrets Manager.

It expects to find the Secrets Manager configuration file at .config/keeper/ssh-sign.json in the user's home directory for all systems. If this configuration is not found, it will check ssh-sign.json as a backup. The Secrets Manager application must have access to the shared folder in which your SSH key is stored.

For help in setting up your application and obtaining your configuration file, you can find detailed instructions here.

2. Git Config

After successfully configuring Secrets Manager, you can now configure git to sign your commits automatically. This can be done locally or globally, depending on your needs.

Four pieces of information are required in your config:

  1. Tell git you want to sign all commits.

  2. Tell git you want to use SSH signing over the default GPG signing.

  3. Tell git the location of this integration's executable file. (download here)

  4. Tell git the UID of the SSH key to be used to sign.

We can do this for the local Git repository with the following commands (add the --global flag to set these globally):

git config commit.gpgsign true
git config gpg.format ssh
git config gpg.ssh.program <path to this binary>
git config user.signingkey <SSH Key UID>

Your git config will now include these attributes:

[commit]
	gpgsign = true
[gpg]
	format = ssh
[user]
	signingKey = <SSH Key UID>
[gpg "ssh"]
	program = path/to/ssh-sign

3. Add Keys to GitHub / GitLab

3.1 Setup GitHub

For GitHub to verify the signature used to sign the commit, you will need to upload your SSH key's public key to your GitHub account. GitHub will then use this public key to verify the signature and display the verified tag in the UI.

For full details on adding your public key to your account, see GitHub's official documentation.

Important: Be sure to set the type of key to "signing key".

3.2 Setup GitLab

For GitLab to verify the signature used to sign the commit, you will need to upload your SSH key's public key to your GitLab account. GitLab will then use this public key to verify the signature and display the verified tag in the UI.

For full details on adding your public key to your account, see Gitlab's official documentation.

Important: Be sure to set the type of key to "signing key" or "Authentication and signing".

Verify Signatures

Git is now configured to automatically sign all commits, regardless of whether you use the terminal or an IDE interface to interact with git. It also removes the need to use the -S flag for commit signing.

You can confirm your commit has been signed with git show --pretty=raw in the terminal.

GitHub and GitLab

Once you have signed a commit and pushed it to GitHub or GitLab, you should see the verified tag next to your commit in the Git history automatically. No further work is needed.

Local verification

If your repos are stored in your own datacenter, you can verify commits locally on the command line. In order to so this, you will need to create an allowed_signers file which is a record of authorized signing keys.

Typically, this file is saved either globally at .ssh/allowed_signers or in the local repo at .git/allowed_signers. The path to this file needs then to be added to your .gitconfig or .git/config file.

git config gpg.ssh.allowedSignersFile path/to/file

Each line of your allowed_signers file should be a principal of an authorized signing key. The line should start with the email address associated with the public key, separated by a space. For example:

test@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQvSrBv28KLAjYO7pD91prhlenrm3hZ4B7DdcB/4/H+

The format of the allowed signers file is documented in full here.

While it is correct syntax to have more than one email address associate with a single public key, it is not recommended or currently supported.

To verify your git history use:

# Verify all commits in the repo
git log --show-signature

# Verify the last commit in the repo
git log --show-signature -1

Source

The source code for this integration is open source and available on GitHub. Issues can be submitted here.

Similar Integrations

Keeper also provides the ability to authenticate and sign Git commits using the Keeper SSH Agent.

  • Learn more about the Keeper SSH Agent and specifically Integration with Git

GitHub Actions

Keeper Secrets Manager integration into GitHub Actions for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault within the Github Actions runner

  • Set secret credentials as build arguments or environment variables in Github Actions scripts

  • Copy secure files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Video Demo

The below overview video covers basic setup and ends with a basic Github Actions integration.

Prerequisites

This page documents the Secrets Manager GitHub Actions integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The GitHub Actions integration accepts JSON and Base64 format configurations

About

This action securely retrieves secrets from Keeper and places them to the desired destination of the GitHub Actions runner such as an environment variable, output parameters of the step or to the file.

Quick Start

Below example shows all available functionality of this plugin

on: 
  push:
    branches: [ master ]

jobs:
  buildexecutable:
    runs-on: ubuntu-latest
    name: Build with Keeper secrets
    steps:

      - name: Retrieve secrets from Keeper
        id: ksecrets
        uses: Keeper-Security/ksm-action@master
        with:
          keeper-secret-config: ${{ secrets.KSM_CONFIG }}
          secrets: |-
              # Reference records by UID
              uid123/field/password > PASSWORD
              uid234/field/password > env:PASSWORD
              uid234/field/login > LOGIN
              uid234/custom_field/Cust1 > env:CUST1
              uid321/file/Certificate.crt > file:/tmp/Certificate.crt
              # Reference records by title - see Keeper Notation for full detail
              Server1/field/password > PASSWORD1
              Server2/field/password > PASSWORD2

      # View secret stored into 'PASSWORD' environment variable
      - name: Print password
        run: |
          echo "Password is ${{ env.PASSWORD }}"
          echo "Login is ${{ steps.ksecrets.outputs.LOGIN }}"

You will need to provide two inputs to utilize the Github Actions plugin:

  • A Keeper Secrets Manager configuration

    • Github Actions supports JSON type configuration

  • Keeper Notation queries for secrets

Inputs

keeper-secret-config

Secrets configuration. See documentation for more information about creating a configuration.

JSON type configuration is supported.

Example:

keeper-secret-config: ${{ secrets.KSM_CONFIG }}

We recommend storing the configuration in a Github Actions secret and accessing it as a variable, as shown in the example above.

secrets

Queries using Keeper Notation to access fields in Keeper records.

The secrets input is the list of secrets that you need to get from Keeper and put into either an environment variable, GitHub Action output or a file.

Example:

secrets: |-
  # Reference records by UID
  uid123/field/password > APP_PASSWORD
  uid234/field/password > env:DB_PASSWORD
  uid321/file/Certificate.crt > file:/tmp/Certificate.crt
  # Reference records by title - see Keeper Notation for full detail
  App1/field/password > PASSWORD1
  DB2/field/password > PASSWORD2

The first part is the id of the secret using the Keeper Notation format.

The second part defines the destination of the secret in the GitHub runner.

Notation\Destination prefix
Default (empty)
env:
file:

field or custom_field

Notation query result is placed into step's output

Notation query result is placed into environment variable

Not allowed

file

file is downloaded and placed into destination

file is downloaded and placed into destination

file is downloaded and placed into destination

Masking - Hiding Secrets from Logs

This action uses GitHub Action's built-in masking, so all variables will automatically be masked if printed to the console or to logs. This only obscures secrets from output logs. If someone has the ability to edit your workflows, then they are able to read and therefore write secrets to somewhere else just like normal GitHub Secrets.

Source Code

Find the Keeper Secrets Manager Github Actions plugin source code in the GitHub repository

GitLab

Keeper Secrets Manager integration into GitLab for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault within the GitLab Pipeline

  • Set secret credentials as build arguments or environment variables

  • Copy secure files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager GitLab integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The GitLab integration accepts JSON and Base64 format configurations

  • A GitLab account with Pipeline creation access

    • Python3 installed to the GitLab Pipeline job

About

This action securely retrieves secrets from Keeper and places them to the desired destination of the GitLab Pipeline such as an environment variable or file.

Setup

Save Configuration as a Secret Variable

A keeper Secrets Manager configuration is required to utilize the GitLab integration.

1) Create a Keeper Secrets Manager Configuration. See the documentation for details. The GitLab integration supports Base64 and JSON configurations.

2) To save the configuration in GitLab, navigate to GitLab Settings -> CI/CD -> Variables

3) Create a new variable. Key can be set to any name for the variable (use KSM_CONFIG to have the SDKs automatically recognize the configuration). Set Value as the Secrets Manager configuration in Base64 or JSON format.

Use KSM_CONFIG as the variable name to have Secrets Manager SDKs automatically recognize the configuration variable

After creating the variable, you should see it in your GitLab variables as shown below.

Keeper Secrets Manager GitLab Integration setup is complete

Usage

Prepare the Pipeline for Secrets Manager

In order to use Keeper Secrets Manager with GitLab, first we need to install it from the PyPi registry. This can be achieved by adding following line to the before_script area:

before_script:
  - python3 -m pip install keeper-secrets-manager-cli

If you did not set the Secrets Manager Configuration variable to the name KSM_CONFIG you need to set it here in the before_script area

  - export KSM_CONFIG=$<SECRETS MANAGER CONFIG VARIABLE>

Get Secrets

Inside the GitLab job, retrieve a secrets from the Keeper Vault using the following format:

$(ksm secret notation <KEEPER NOTATION>)

This utilizes the KSM CLI tool to get secrets using Keeper Notation.

After getting a secret, you can set it as an environment variable or file.

Set Secret as Environment Variable

Use - export <VARIABLE NAME>=$(ksm secret notation <KEEPER NOTATION>) to set a secret to an environment variable

Example:

The following job sets a password secret as an environment variable named MY_PWD and a custom 'isbncode' record field to the environment variable named MY _ISBNCODE

job1:
  stage: build
  script:
    - export MY_PWD=$(ksm secret notation keeper://XXX/field/password)
    - export MY_ISBNCODE=$(ksm secret notation keeper://XXX/custom_field/isbncode)

Replace XXX with a record UID in the above example.

Keeper Secrets Manager can be used in any job stage. This example uses the build stage.

Create a File from a Secret

Use - ksm secret download -u <UID> --name <SECRET FILENAME> --file-output "<OUTPUT FILENAME>" to get a file from the Keeper Vault and save it as a file to your GitLab Pipeline job.

Example:

The following job gets a file named "mykey.pub" that is attached to a Keeper record and saves its contents into file name "mykey.pub" in the local "tmp" folder

job1:
  stage: build
  script:
   - ksm secret download -u XXX --name "mykey.pub" --file-output "/tmp/mykey.pub"

Replace XXX with a record UID in the above example.

Keeper Secrets Manager can be used in any job stage. This example uses the build stage.

Complete Example

The example below shows all available functionality of this integration

image: python:latest

before_script:
  - python3 -m pip install keeper-secrets-manager-cli

job1:
  stage: build
  script:
    - export MY_PWD=$(ksm secret notation keeper://XXX/field/password)
    - export MY_ISBNCODE=$(ksm secret notation keeper://XXX/custom_field/isbncode)
    - ksm secret download -u XXX--name "mykey.pub" --file-output "/tmp/mykey.pub"
    - file /tmp/mykey.pub

Replace XXX in the example above with a record UID.

Google Cloud Secret Manager Sync

Sync secrets from the Keeper Vault with GCP Secret Manager

About

The Keeper Secrets Manager CLI tool sync command allows you to push secrets from the Keeper Vault to a target GCP Secret Manager project, overwriting the existing values in the target location. This allows the Keeper Vault to be the single source of truth for any services or scripts in GCP that utilize GCP Secret Manager.

Features

  • Use secrets from the Keeper Vault as the source of truth for GCP Secret Manager

  • Seamlessly start using secrets from the Keeper Vault with your existing GCP scripts and services

Prerequisites

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper subscription

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A GCP account with GCP Secret Manager, and optionally the ability to create IAM service account credentials

Setup

1. Configure Keeper Secrets Manager CLI

You can skip this step if the KSM CLI is already configured on your machine.

To configure the KSM CLI tool, a profile needs to be created with the Keeper Secrets Manager One Time Access Token.

The simplest way to do this is to initialize the default profile with the following command:

ksm profile init <TOKEN>

For information on creating multiple profiles and other options, see the profile documentation

2. Set GCP Permissions

To use the KSM sync to GCP, GCP Secrets Manager requires standard IAM security credentials with Secret Manager Admin role enabled for the project or on the service account principal to sync.

Secret Manager Access control with IAM:

https://cloud.google.com/secret-manager/docs/access-control

GCP instructions for creating Service Account Credentials (optional):

https://developers.google.com/workspace/guides/create-credentials#service-account

3. Create GCP Credentials Record

The KSM CLI needs the credentials for the GCP service account to set secrets. These credentials are stored in a Keeper record which the CLI tool can access using Keeper Secrets Manager.

Record fields with the following labels are required on the credentials record:

"Google Cloud Project ID" "Google Application Credentials" - optional

"Google Application Credentials" field is optional and needed only when Service Account Credentials are used. By default, GCP clients use Application Default Credentials which can be created using gcloud CLI

gcloud auth application-default login

When no longer need these credentials can be revoked:

gcloud auth application-default revoke

(Method 1) Create a GCP Credentials Custom Record Type

A custom record type can be created with the required fields, which makes it easy and clean to create a record.

To create a custom record type, go to the "Custom Record Types" tab in the Keeper Vault and hit "Create Type". Create a new record type with hidden fields that have the correct field label, then click "Publish" to create the new record type.

GCP Credentials Record Type Definition
GCP Credentials Record Type Definition

Then simply create a new record of the GCP Credentials type and enter the details into the corresponding fields.

GCP Credentials Record Create
GCP Credentials Record Create

Make sure this new record is moved to a Shared Folder that is associated with your Secrets Manager application.

(Method 2) Add Custom Fields

To create a credentials record without creating a new record type, the required fields can be added as custom fields to a standard record.

Create a new record of any type, then add Custom Fields of the 'Hidden Field' type for each required GCP field. Click "Edit Label" to change the labels for the corresponding field name.

Any record type will work, but the "File Attachment" standard record type has no fields and will be cleaner looking when custom fields are added

GCP Credentials fields as custom fields
GCP Credentials fields as custom fields

Then fill in each custom field and hit "Save" to save the record.

4. Create Value Mappings

The KSM CLI sync command identifies which values to set using mappings that are defined on the command call. For each mapping passed to the command, a value with the given name will be populated with the given value from the Keeper Vault.

These mappings follow this format:

--map "VALUE KEY" "KEEPER NOTATION"

VALUE KEY is the key name that the value will be assigned in GCP Secret Manager

KEEPER NOTATION is a Keeper notation query of a value from a keeper record to set to the key

Keeper notation is a query notation used by Keeper Secrets Manager to identify specific record values. The notation follows the general format of: UID/[field|custom_field]/fieldname for example: ae3d[...]d22e/field/password

See the Keeper Notation documentation for more information

Note that full record UIDs are not given in these examples

Full Mapping Example: --map "MySQL_PWD" "jd3[...]i-fd/field/password"

Multiple mappings can be added to a single sync command --map "MySQL_PWD" "jd3[...]i-fd/field/password" --map "MySQL_Login" "jd3[...]i-fd/field/login"

Ensure that the records referenced by the Keeper Notation queries are in a shared folder that is shared with your Secrets Manager application

KSM sync is now ready to run

Run Sync

To run the sync, use the KSM CLI sync command with the credentials record and value mapping.

1. Construct the Command

Put together the KSM sync command with the GCP type. The format looks like the following:

ksm sync --type gcp --credentials [UID] --map [...] --map [...]

2. Run a Dry-Run

The sync command supports running a dry-run which will identify all changes that will be made to your GCP Secret Manager values without actually pushing the values or making changes. Use this to make sure your mapping queries are constructed properly.

ksm sync --type gcp --credentials [UID] --map [...] --map [...] --dry-run

3. Run the Sync

When ready, run the sync command without the dry-run option. This will push values from your Keeper Vault to GCP Secret Manager

TIP: you can use -m as short hand for --map

ksm sync --type gcp --credentials [UID] -m [...] -m [...]

Google Cloud Key Management Encryption

Protect Secrets Manager connection details with Google Cloud Key Management

Keeper Secrets Manager integrates with Google Cloud Key Management in order to provide encryption for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all your secret credentials.

Features

  • Encrypt and Decrypt your Keeper Secrets Manager configuration files with Google Cloud Key Management.

  • Protect against unauthorized access to your Secrets Manager connections.

  • Requires only minor changes to code for immediate protection. Works with all Keeper Secrets Manager SDK functionality.

Prerequisites

To configure, Google Cloud Key Management with Keeeper Security you need service account keys ended with .json . Key structure that is supported by this integration is `projects/<project_name>/locations/<location_name>/keyRings/<key_ring_name>/cryptoKeys/<key_name>/cryptoKeyVersions/<key_version>`

  • Support the Java/Kotlin Secrets Manager SDK.

  • Required GCP package google-cloud-kms

  • Google Cloud Key Management needs ENCRYPT and DECRYPT permissions.

  • Supports the JavaScript Secrets Manager SDK

  • Requires the @google-cloud/kms package from GCP SDK.

  • GCP CKM Key needs ENCRYPT and DECRYPT permissions.

  • Supports the Python Secrets Manager SDK

  • Requires google-cloud-kms package

  • GCP CKM Key needs ENCRYPT and DECRYPT permissions.

  • Supports the .Net Secrets Manager SDK

  • Requires Google.Apis.CloudKMS.v1

  • GCP CKM Key needs ENCRYPT and DECRYPT permissions.

  • Supports the GoLang Secrets Manager SDK

  • Requires the kms/apiv1 , kmspb , core, kms package from GCP SDK.

  • GCP CKM Key needs ENCRYPT and DECRYPT permissions.

Setup

1. Install Module

Setting up project using Gradle or Maven

Gradle

repositories {
  mavenCentral()
}

dependencies {
	implementation("com.keepersecurity.secrets-manager:core:17.0.0")
	implementation("com.keepersecurity.secrets-manager:gcp:1.0.0")
	implementation ("com.google.cloud:google-cloud-kms:2.62.0")
	implementation ("com.google.auth:google-auth-library-oauth2-http:1.33.1") 
	implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
	implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
	implementation("com.google.code.gson:gson:2.12.1")
    implementation("org.slf4j:slf4j-api:1.7.32"){
        exclude("org.slf4j:slf4j-log4j12")
    }
	implementation("ch.qos.logback:logback-classic:1.2.6")
	implementation("ch.qos.logback:logback-core:1.2.6")
	implementation("org.bouncycastle:bc-fips:1.0.2.4")
}

Maven

<!-- KMS-core -->
<dependency>
	<groupId>com.keepersecurity.secrets-manager</groupId>
	<artifactId>core</artifactId>
	<version>[17.0.0,)</version>
</dependency>
<dependency>
	<groupId>com.keepersecurity.secrets-manager</groupId>
	<artifactId>gcp</artifactId>
	<version>1.0.0</version>
</dependency>
<!-- gcp-kms -->
<dependency>
	<groupId>com.google.cloud</groupId>
	<artifactId>google-cloud-kms</artifactId>
	<version>2.62.0</version>
</dependency>
<!-- gcp auth -->
<dependency>
	<groupId>com.google.auth</groupId>
	<artifactId>google-auth-library-oauth2-http</artifactId>
	<version>1.33.1</version>
</dependency>
<!--gson -->
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.12.1</version>
</dependency>
<!--jackson-core -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.18.2</version>
</dependency>
<!--jackson-databind -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.18.2</version>
</dependency>
<!-- slf4j-api -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.32</version>
	<scope>runtime</scope>
</dependency>
<!-- logback-classic -->
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.6</version>
	<scope>compile</scope>
</dependency>
<!-- logback-core -->
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-core</artifactId>
	<version>1.2.6</version>
	<scope>compile</scope>
</dependency>
<!-- bc-fips -->
<dependency>
	<groupId>org.bouncycastle</groupId>
	<artifactId>bc-fips</artifactId>
	<version>1.0.2.4</version>
</dependency>

The Secrets Manager Google Cloud Key Management module can be installed using npm

npm install @keeper-security/secrets-manager-gcp

The Secrets Manager Google Cloud Key Management module can be installed using pip

pip3 install keeper-secrets-manager-storage-gcp-kms

The Secrets Manager Google Cloud Key Management module can be installed using dotnet nuget package manager.

dotnet add package Keeper.SecretsManager.GCPKeyManagement

The Secrets Manager Google Cloud Key Management module Integration can be installed using

go get github.com/keeper-security/secrets-manager-go/integrations/gcp

2. Configure Google CKM Connection

To enable secure authentication with Google Cloud Platform (GCP), generate a Service Account key in JSON format. This credential file will serve as the authentication mechanism for interacting with GCP services programmatically.

See the Google documentation for more information on generating keys:

https://cloud.google.com/iam/docs/keys-create-delete

3. Add GCP Key Vault Storage to Your Code

Once GCP connection has been configured, You can fetch the Key to encrypt / decrypt KSM configuration using integration and you need to tell the Secrets Manager SDK to utilize the KMS as storage.

Using GCP Key Vault Integration

Once setup, the Secrets Manager GCP Key Vault integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the GCP CKM Keys in order to manage the encryption and decryption of the KSM configuration file. Using Specified Connection credentials

To do this, create GcpKeyValueStorage instance and use this in SecretManagerOptions constructor.

The GcpKeyValueStorage will require the name of the Secrets Manager configuration file , gcp credential file and key details of Cloud Key Management.

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretsmanager.gcp.GcpKeyValueStorage;
import com.keepersecurity.secretsmanager.gcp.GcpSessionConfig;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
public class Test {
	public static void main(String args[]){
	    String oneTimeToken = "One_Time_Token";
	    String projectId = "projectId";
	    String location = "cloud_region";
	    String keyRing = "key_ring_name";
	    String keyId = "key_id";
	    String keyVersion = "key_version";
	    String configFileLocation = "client_config_test.json";
	    String credentialFileLocation = "<path_with_name_of_gcp_cred_file.json>";
	    Security.addProvider(new BouncyCastleFipsProvider());
		try{
				GcpSessionConfig sessionConfig = new GcpSessionConfig(projectId, location, keyRing, keyId, keyVersion, credentialFileLocation);
				GcpKeyValueStorage storage = new GcpKeyValueStorage(configFileLocation, sessionConfig);
				initializeStorage(storage, oneTimeToken);
				SecretsManagerOptions options = new SecretsManagerOptions(storage);	
		}catch (Exception e) {
				  System.out.println(e.getMessage());
		}
	}
}

To do this, use GCPKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an keyConfig , gcpsessionConfig(generated by GCPKSMClient) , and the name of the Secrets Manager configuration file which will be encrypted by GCP Cloud Key Management.

 import {GCPKeyValueStorage,GCPKeyConfig,GCPKSMClient,LoggerLogLevelOptions} from "@keeper-security/secrets-manager-gcp";
    const getKeeperRecordsGCP = async () => {
        const gcpCredFile = "<path_with_name_of_gcp_cred_file.json>"
        const keyConfig2  = new GCPKeyConfig("<key_version_resource_url_1>");
        const keyConfig = new GCPKeyConfig("key_version_resource_url_2");
        const gcpSessionConfig = new GCPKSMClient().createClientFromCredentialsFile(gcpCredFile)
        let config_path = "<path to client-config.json>"
        let logLevel = LoggerLogLevelOptions.debug;
        const oneTimeToken = "<one_time_token>";
        const storage = await new GCPKeyValueStorage(config_path, keyConfig, gcpSessionConfig, logLevel).init();
        await initializeStorage(storage, oneTimeToken);
        const {records} = await getSecrets({storage: storage});
        console.log(records)
        const firstRecord = records[0];
        const firstRecordPassword = firstRecord.data.fields.find((x: { type: string; }) => x.type === 'bankAccount');
        console.log(firstRecordPassword.value[0]);
    }
    console.log("start")
    getKeeperRecordsGCP()

To do this, use GCPKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require gcp_key_config (generated by GCPConfig ), gcp_session_config object (generated by GCPKMSClientConfig ) and the name of the Secrets Manager configuration file which will be encrypted by GCP Cloud Key Management.

from keeper_secrets_manager_storage_gcp_kms import GCPKeyConfig, GCPKeyValueStorage, GCPKMSClientConfig
from keeper_secrets_manager_core import SecretsManager

# Example key: projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key_name>/cryptoKeyVersions/<version>
gcp_key_config_1 = GCPKeyConfig("<key_resource_uri_1>")
gcp_key_config_2 = GCPKeyConfig("<key_resource_uri_2>")

gcp_cred_file_location_with_name = "<path_with_name_of_gcp_cred_file.json>"
gcp_session_config = GCPKMSClientConfig().create_client_from_credentials_file(gcp_cred_file_location_with_name)

config_path = "ksm_config.json"
one_time_token = "<one_time_token>"

storage = GCPKeyValueStorage(config_path, gcp_key_config_1, gcp_session_config)
secrets_manager = SecretsManager(token=one_time_token, config=storage)
all_records = secrets_manager.get_secrets()

first_record = all_records[0]
print(first_record)

To do this, use GCPKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an keyConfig (generated by GCPKeyConfig ), gcpSessionConfig object (generated by GCPKMSClient ), and the name of the Secrets Manager configuration file which will be encrypted by GCP Cloud Key Management.

 using System;
 using System.Linq;
 using System.Threading.Tasks;
 using SecretsManager;
 using GCPKeyManagement;
 using Microsoft.Extensions.Logging;
 public class Program {
   private static async Task getOneIndividualSecret() {
     Console.WriteLine("execution started");
     string key1ResourceName = "<KEY1ResourceURL>";
     string key2ResourceName = "<Key2ResourceURL>";
     string gcpConfigFilePath = "<GCP config file path with name>";
     var keyConfig = new GCPKeyConfig(key1ResourceName);
     var gcpSessionConfig = new GCPKMSClient().CreateClientFromCredentialsFile(gcpConfigFilePath);
     var ksmConfigPath = "ksm_config.json";
     var dotnet_access_token = "[One_Time_Token]";
     var loggerFactory = LoggerFactory.Create(builder => {
       builder.SetMinimumLevel(LogLevel.Debug);
       builder.AddConsole();
     });
     var logger = loggerFactory.CreateLogger < GCPKeyValueStorage > ();
     var gcp_storage = new GCPKeyValueStorage(keyConfig, gcpSessionConfig, ksmConfigPath, logger);
     SecretsManagerClient.InitializeStorage(gcp_storage, dotnet_access_token);
   }
   static async Task Main() {
     await getOneIndividualSecret();
   }
 }

To do this, use NewGCPKeyVaultStorage as your Secrets Manager storage in the NewSecretsManager

The NewGCPKeyVaultStorage requires the following parameters to encrypt the KSM configuration using GCP Cloud Key Management:

ksmConfigFileName : The file name of KSM configuration.

keyResourceName : ProvidekeyResourceName of Google Cloud Key Management

credentialFileWithPath : Provide file path with name of GCP credential file.

package main
import (
	"encoding/json"
	"fmt"
	"github.com/keeper-security/secrets-manager-go/core"
	gcpkv "github.com/keeper-security/secrets-manager-go/integrations/gcp"
)
func main() {
	credentialFileWithPath := "<Location of credential file ending with .json>"
	keyResourceName := "<Key_Resource_Name>"
	ksmConfigFileName := "ksmConfig.json"
	oneTimeToken := "<One_Time_Access_Token>"
	cfg := gcpkv.NewGCPKeyVaultStorage(ksmConfigFileName, keyResourceName, credentialFileWithPath)
	client_options := &core.ClientOptions{
		Token:  oneTimeToken,
		Config: cfg,
	}
	fmt.Printf("Client ID Value: %s", cfg.Get(core.KEY_CLIENT_ID))
	secrets_manager := core.NewSecretsManager(client_options)
	secrets, err := secrets_manager.GetSecrets([]string{})
	if err != nil {
		// do something
		fmt.Printf("Error while fetching secrets: %v\n", err)
	}
	for _, record := range secrets {
		fmt.Printf("Records: %v\n", record)
	}
}

Additional Options

Change Key

We can change key that is used for encrypting the KSM configuration, examples below show the code needed to use it

//The method changeKey(keyID) will be used to encrypt the KSM config file with new Key and version. 
GcpKeyValueStorage storage = new GcpKeyValueStorage(configFileLocation, sessionConfig);
String newKeyID = "<new Key ID>";
boolean isChanged = storage.changeKey(keyId);
System.out.println("Key Changed: "+isChanged); // Change the key for encryption/decryption
// To change the GCP CKM key used for encryption, you can call the `changeKey` method on the `OciKeyValueStorage` instance.
const storage = await new GCPKeyValueStorage(configPath,keyConfig,gcpSessionConfig).init();
await storage.changeKey(keyConfig2);
storage = GCPKeyValueStorage(config_path, gcp_key_config_1, gcp_session_config)
is_changed = storage.change_key(gcp_key_config_2)
print("Key is changed:", is_changed)
// To change the Google CKM key used for encryption, you can call the `ChangeKeyAsync` method on the `GCPKeyValueStorage` instance.
// using Microsoft.Extensions.Logging;
var gcp_storage = new GCPKeyValueStorage(keyConfig2, gcpSessionConfig, path,logger);
bool isChanged = gcp_storage.ChangeKeyAsync(keyConfig1).Wait();
Console.WriteLine(isChanged)
// If you want to change the key not gcpp config, then pass nil in place of oracle config.
cfg := gcpkv.NewGCPKeyVaultStorage(ksmConfigFileName, keyResourceName, credentialFileWithPath)
updatedResourceName := "<Updated Key Resource Name>"
isChanged, err := cfg.ChangeKey(updatedResourceName, "")
	if err != nil {
		// do something
	}
fmt.Printf("Key changed: %v\n", isChanged)

Decrypt Config

We can decrypt the config if current implementation is to be migrated onto a different cloud or if you want your raw credentials back. The function accepts a boolean which when set to true will save the decrypted configuration to file and if it is false, will just return decrypted configuration.

GcpKeyValueStorage storage = new GcpKeyValueStorage(configFileLocation, sessionConfig);
storage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
//OR 
storage.decryptConfig(true); // Set true as a parameter to extract plaintext and save config as a plaintext.
const storage = await new GCPKeyValueStorage(configPath,keyConfig,gcpSessionConfig).init();
await storage.decryptConfig(true); // Set true as a parameter to extract plaintext and save config as a plaintext.
 // OR 
await storage.decryptConfig(false);  // Set false as a parameter to extract only plaintext.
storage = GCPKeyValueStorage(config_path, gcp_key_config_1, gcp_session_config)

# Extract only plaintext
plaintext = storage.decrypt_config(False)
print(plaintext)

# OR extract plaintext and save config as plaintext
plaintext = storage.decrypt_config(True)
print(plaintext)
# To decrypt the config file and save it again in plaintext, you can call the `DecryptConfigAsync` method on the `OracleKeyValueStorage` instance.
var gcp_storage = new GCPKeyValueStorage(keyConfig2, gcpSessionConfig, path,logger);
var conf = await gcp_storage.DecryptConfigAsync(false); # Set false as a parameter to extract only plaintext.
Console.WriteLine(conf);
# OR
var conf = await gcp_storage.DecryptConfigAsync(true); # Set true as a parameter to extract plaintext and save config as a plaintext.
Console.WriteLine(conf);
cfg := gcpkv.NewGCPKeyVaultStorage(ksmConfigFileName, keyResourceName, credentialFileWithPath)
plainText, err := cfg.DecryptConfig(false)
if err != nil {
	// do something
	fmt.Printf("Error while decrypting config: %v", err)
}  
plainText, err := cfg.DecryptConfig(true) // Set true as a parameter to extract plaintext and save config as a plaintext.
if err != nil {
	// do something
	fmt.Printf("Error while decrypting config: %v", err)
}  

You're ready to use the KSM integration 👍

Check out the KSM SDKs documentation for more examples and functionality

Hashicorp Vault

Use Keeper Secrets Manager with HashiCorp Vault as a Data Source

About

The Keeper Secrets Manager HashiCorp Vault integration allows you to use secrets from the Keeper Vault as a data store for HashiCorp Vault.

Features

  • Use Secrets from the Keeper Vault with HashiCorp Vault scripts and commands

  • Read secret information using HashiCorp Vault

  • Update secret information from HashiCorp Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager HashiCorp Vault integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper subscription

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The HashiCorp Vault integration accepts our Base64 format configurations

  • HashiCorp Vault command line, and a Vault server running

    • See the HashiCorp Vault documentation for how to install

Installation

1. Download the Secrets Manager Plugin

Download the latest integration release from the KSM GitHub page:

LogoReleases · Keeper-Security/secrets-managerGitHub
Secrets Manager Releases

Look for a vault-plugin release in the list of releases that matched your platform.

Unzip the plugin and place it into your HashiCorp Vault plugins directory. In this example the folder is located at C:\vault\plugins (Windows) or /etc/vault/vault_plugins (MacOS/ Linux)

2. Register the Plugin with HashiCorp Vault

Development Mode

For testing the plugin or to allow quick development, development mode can be used to quickly get the HashiCorp Vault CLI up and running.

Start the HashiCorp Vault in dev mode

vault server -dev -dev-plugin-dir=C:\vault\plugins

Enable the Secrets Manager Plugin

vault secrets enable -path=ksm vault-plugin-secrets-ksm.exe

Start the HashiCorp Vault in dev mode

vault server -dev -dev-plugin-dir=/etc/vault/vault_plugins

Enable the Secrets Manager Plugin

vault secrets enable -path=ksm vault-plugin-secrets-ksm

HashiCorp Vault CLI development mode utilizes volatile in-memory storage. Any actions taken on secrets in the Keeper Vault are immediate, but the plugin will need to be re-enabled each time the HashiCorp Vault is started in dev mode.

Production Mode

When ready to move to production, the plugin will need to be registered using a SHA256 hash of the plugin.

Register and Enable the Secrets Manager Plugin

vault plugin register -command=vault-plugin-secrets-ksm.exe -sha256=<SHA256> secret vault-plugin-secrets-ksm
vault secrets enable -path=ksm vault-plugin-secrets-ksm

Generating SHA256 Hash

You will need a hash of the plugin file to enable it with production HashiCorp Vault servers. This hash can be generated for the Secrets Manager plugin.

Windows 7 and later comes with a built-in tool called CertUtil that can be used to generate the SHA256 hash. This example will show how to generate a SHA hash using CertUtil, but any tool that can generate a file hash in SHA256 will work.

CertUtil -hashfile C:\vault\plugins\vault-plugin-secrets-ksm.exe SHA256

Register and Enable the Secrets Manager Plugin

vault plugin register -sha256=<SHA256> secret vault-plugin-secrets-ksm
vault secrets enable -path=ksm vault-plugin-secrets-ksm

Generating SHA256 Hash

You will need a hash of the plugin file to enable it with production HashiCorp Vault servers. This hash can be generated for the Secrets Manager plugin.

Using the built-in shasum function this can be generated like this:

shasum -a 256 /etc/vault/vault_plugins/vault-plugin-secrets-ksm

Depending on your OS, you may use the sha256sum command instead

sha256sum /etc/vault/vault_plugins/vault-plugin-secrets-ksm

3. Configure a Secrets Manager Connection

Now that the HashiCorp Vault plugin is installed, a secure connection to the Keeper Vault needs to be established so that secret credentials can be accessed. To create this connection, a Secrets Manager configuration needs to be created and assigned to the plugin.

Create a Secrets Manager Configuration

A Secrets Manager configuration can be created using Keeper Commander or the Secrets Manager CLI. See the Configuration Documentation for more information on creating a configuration.

Once a configuration has been generated, set it to a variable to be used by the Vault Plugin.

vault write ksm/config ksm_config=<BASE64_CONFIG...>

Using the Plugin

List Secrets

vault list ksm/records

The records will be shown in the following format:

Keys
----
UID RECORDTYPE: RECORDTITLE

Example:

C:\Vault> vault list ksm/records
Keys
----
Hf6of4uo_2aD7IMjn4VPuA  login:  My Record
Lv3B9ObAjxdpdBl0IJ3oow  folder: 4 record(s)
Oq3fFu14hZY00d7sp3EYNA  MyCustomType:  My New Record (Custom record type)
YDx58Q94dE1k9B367ZVz1w  databaseCredentials:    MySQL Credentials
qe3EWYn840uR0bOMyZ2b0Q  login:  Dropbox Login

Get a Single Secret

vault read ksm/record uid=<UID>

Example:

C:\Vault> vault read ksm/record uid=Hf6r5Zuo_2aD7IMjn4VPuA
Key       Value
---       -----
fields    [map[type:login value:[username@email.com]] map[type:password value:[Pd08fi@1]]]
notes     Example Login Record
title     Sample KSM Record
type      login

Read TOTP Code

vault read ksm/record/totp uid=<UID>

Example:

C:\Vault> vault read ksm/record/totp uid=32t82-oRu-79yplIAZ6jmA 
Key    Value
---    ---
TOTP   [map[token:392528 ttl:22 url:otpauth://totp/Generator:?secret=JBSWY3DPEZAK3PXP&issuer=Generator&algorithm=SHA1&digits=6&period=30]] 
UID    32t82-oRu-79yplIAZ6jmA

Update a Secret

To update an existing secret, use the following command, passing in JSON data that represents the updated secret's information. The corresponding record in the Keeper Vault will be updated to match the JSON data passed.

vault write -format=json ksm/record uid=<UID> data=@update.json

In this example, the updated data is passed in from a file, this is recommended for cleaner and more simple CLI commands. The JSON data can be passed in on the command line, but quotes will need to be escaped.

Example data file:

update.json
{
  "fields": [
    {
      "type": "login",
      "value": [
        "username@email.com"
      ]
    },
    {
      "type": "password",
      "value": [
        "kjh4j3245DCD!d"
      ]
    }
  ],
  "notes": "\tThis record was updated with the Vault KSM plugin",
  "title": "Sample Updated Record",
  "type": "login"
}

TIP You can see the current values of a secret in JSON format with this command: vault read -field=data -format=json ksm/record uid=<UID>

Create a Secret

Similar to updating a secret, create a new secret by passing JSON data to the following command:

vault write -format=json ksm/record/create folder_uid=<UID> data=@data.json

In this example, the updated data is passed in from a file, this is recommended for cleaner and more simple CLI commands. The JSON data can be passed in on the command line, but quotes will need to be escaped.

Example data file:

data.json
{
      "fields": [
             {
      "type": "login",
      "value": [
       "username@email.com"
      ]
    },
    {
      "type": "oneTimeCode",
      "value": [
        "otpauth://totp/Generator:?secret=JBSWY3JP9HPK3PXP\u0026issuer=Generator\u0026algorithm=SHA1\u0026digits=6\u0026period=30"
      ]
    }
  ],
  "notes": "\tExample Record wth TOTP",
  "title": "Sample TOTP SECRET",
  "type": "login"
}

Delete a Secret

vault delete ksm/record uid=Oq3fFu14hZY00d7sp3EYNA

Heroku

Using Keepers Secrets Manager to store your Heroku application sensitive secrets.

Features

  • Securely store secret credentials in the Keeper Vault and use them in Heroku without exposure

  • Copy files from the Keeper vault into your Heroku Apps

  • Utilize other Secrets Manager SDK features (such as record creation and TOTP codes) from Heroku

For a complete list of Keeper Secrets Manager features see the Overview

About

Heroku offers the ability to store configuration variables for your application. The problem is it stores the values in a viewable format. Keeper Secrets Manager allows you to store your sensitive secrets offsite in a zero knowledge environment.

The Keeper Secrets Manager SDK can be used with Heroku

  • Python

  • GoLang

  • Java

  • Javascript

See the example project below to get an idea of the capabilities of Keeper Secrets Manager with Heroku

Example - Slack notification using Python SDK

This example uses the Keeper Secrets Manager SDK to retrieve a webhook token to send messages to a channel in Slack from a Heroku web application.

Slack Setup

The first step is getting a webhook token from your instance of Slack. Login into the Slack website and go to Your Apps.

Create a new app by clicking the Create New App button and selecting From scratch from the dialog box. At this point enter an App Name and select the workspace you want to develop your app in.

Next click the Incoming Webhooks button.

Turn On the Incoming Webhooks. This will show the Webhook URLs for Your Workspace section. Click the Add New Webhook to Workspace button.

Then select a channel in your workspace.

Now at the bottom of the Incoming Webhooks page, there will be a Webhook URL. For this example, Copy the url. This will be placed in Keeper Vault record.

Keeper Vault setup

In the Keeper Vault create a Login record to hold the Slack Webhook URL in the Shared Folder. The Shared Folder can be added used by an Application. Reference the Quick Start Guide for more details.

Copy the Webhook URL into the Website Address field of the Login record and save. Once saved click on the information icon, , of the record to see the Record UID. You can copy a Record UID URL into the clipboard which will contain the actual Record UID. You only need that part of the URL.

Heroku

For this example, a Heroku account and Python 3 are requiered. The next step is to install the Heroku CLI following their instructions.

With the Heroku CLI installed an application can be created.

$ heroku create
Creating app... done, ⬢ random-name-30564
https://random-name-30564.herokuapp.com/ | https://git.heroku.com/random-name-30564.git

The generated name of your application will be different than in this example.

That will create a blank Git repository that will be used for the application. The Git repository can then be cloned. There will be a warning about it being empty. After that change into the repository directory.

$ git clone https://git.heroku.com/random-name-30564.git
Cloning into 'random-name-30564'...
warning: You appear to have cloned an empty repository.

$ cd random-name-30564

With the repository cloned, the config variables can be set. There are two config variables that need to be set. The first is RECORD_UID which the Record UID of the record that contains the Webhook URL. The second is KSM_CONFIG which contains the Base64 encoded Secrets Manager configuration.

See the Configuration documentation for details on creating a Base64 configuration

$ heroku config:set RECORD_UID=XXXXXX
Setting RECORD_UID and restarting ⬢ random-name-30564... done, v11
RECORD_UID: XXXXXX

$ heroku config:set KSM_CONFIG=ewogI ..... Igp9
Setting KSM_CONFIG and restarting ⬢ random-name-30564... done, v11
KSM_CONFIG: ewogI ..... Igp9

With the configuration variables in place, the application can be added. The first step is to defined the requirements for the Python 3 application. The requirements.txt file contains Flask used for the website, slack_sdk used to communicate with Slack, and keeper-secrets-manager-core to communicate with Secrets Manager.

$ cat << EOF > requirements.txt
Flask
slack_sdk
keeper-secrets-manager-core
EOF

In your preferred editor save the contents of the following to app.py.

import os
from flask import Flask, request
from slack_sdk.webhook import WebhookClient
from keeper_secrets_manager_core import SecretsManager

app = Flask(__name__)
secret_manager = SecretsManager()
record_id = os.environ.get("RECORD_UID")
webhook = WebhookClient(secret_manager.get_notation("{}/field/url".format(record_id)))


@app.route('/')
def hello():

    message = request.args.get("message")
    if message is not None and message != "":
        response = webhook.send(text=message)

    html = """
<html>
    <head><title>Send a Slack Message</title></head>
    <body>
        <form method="GET">
            Message:
            <input type="text" name="message" />
            <input type="submit" />
        </form>
    </body>
</html>
    """

    return html


if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

This is a simple Flask web application that will display a form input box and a submit button. Any text entered into the input box will be sent to your Slack channel.

The last part is to give Heroku information on how to start your application using the Procfile file.

$ cat << EOF > Procfile
web: python app.py
EOF

Now the application is ready to be run. Add the file it your the Git repository and push the main branch. This will build and launch the application.

$ git add requirements.txt app.py Procfile
$ git commit -m "Initial Commit"
[main 0f31f23] Initial Commit
 3 file changed, 0 insertion(+), 0 deletion(-)
...

$ git push origin main
...
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: heroku/python
remote: -----> Python app detected
remote: -----> No Python version was specified. Using the same version as the last build: python-3.9.9
remote:        To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> No change in requirements detected, installing from cache
remote: -----> Using cached install of python-3.9.9
remote: -----> Installing pip 21.3.1, setuptools 57.5.0 and wheel 0.37.0
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 62.4M
remote: -----> Launching...
remote:        Released v13
remote:        https://random-name-30564.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/random-name-30564.git
   89b16a2..fda1835  main -> main

At this point you can visit the web site by either going to the URL, i.e. https://random-name-30564.herokuapp.com/, or by using the following command line.

$ heroku open

This will display a simple web site. Enter a message and click submit.

The message should appear in the channel for the created Webhook.

Jenkins Plugin

Keeper Secrets Manager integration into Jenkins for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault with Jenkins

  • Use Keeper Secrets Manager with Jenkins Freestyle or Jenkins Pipeline projects

  • Get files from the Keeper vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Jenkins integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A One Time Access Token

The plugin uses SecureRandom which can be slow on certain systems due too low entropy. On Linux, executing cat /proc/sys/kernel/random/entropy_avail will show the available entropy. If below 200, you'll need to software like rng-tools to generate entropy.

About

The Jenkins plugin for Keeper Secrets Manager allows you retrieve secrets from the Keeper Vault and place the values into environmental variables or files within the builder and workflow pipelines.

Installation

The Keeper Secrets Plugin can be installed from Jenkins' the list of available plugins. Within Jenkins navigate to Manage Jenkins->Manage Plugins->Available. Search for "Keeper Secrets Manager" using the search bar to find the plugin. Check the Install checkbox and an Install button. You can choose to restart Jenkins immediately, or later to complete installation. When Jenkins restarts, you will be able to use the plugin.

If you had installed a beta version of the Keeper Secrets Manager plugin you will need to remove it first. On the tab Manage Jenkins->Manage Plugins->Installedclick the Uninstall button. It will not show up on the Available tab if already installed.

Source Code

Find the Keeper Secrets Manager Jenkins Plugin source code in the GitHub repository

Create a Secrets Manager Client

If you haven't done so already, follow the Quick Start Guide and create a Secrets Manager application and Client Device specifically for Jenkins usage.

Using Keeper Commander, generate a Client Device for Jenkins. Make note of the One Time Access Token.

My Vault> secrets-manager client add --app MyApplication

------------------------------------------------------------------
One Time Access Token: XX:XXXXXXXXXXXXX
------------------------------------------------------------------

By default, the Client Device is locked to the first IP address that uses the One Time Access Token. If your Jenkins server has potentially multiple external IP addresses, you may want to add the--unlock-ipparameter when generating the One Time Access Token.

For more information on creating Secrets Manager Applications and Clients, see the Secrets Manager Commands documentation.

Add Credential to Jenkins

The first step in using the plugin is creating a Jenkins credential from a One Time Access Token.

Within Jenkins, navigate to Manage Jenkins > Manage Credentials > (scope) > Add Credentials, then select Keeper Secrets Manager in the Kind dropdown. You will be presented with a form that looks like the following:

Set a Description for the credential to make it easier to find in other areas of Jenkins.

Paste the One Time Access Token into the form field and save.

Initial Connection

When you save the credential, the Jenkins server will connect to the Keeper Secrets Manager service and initialize the One Time Access Token. It will then populate the required encryption keys and client identifiers inside Jenkins for subsequent requests. At this point the One Time Access Token field will be cleared out.

If there was a problem initializing the One Time Access Token, the error message will be placed in the field. The Jenkins credential cannot be used until there is no errors. You are able to create a new One Time Access Token and replace the information that already existing for a credential. Just use Commander to create another token, cut-n-paste it into the Token field, and save.

You will not be able to see the Client Id, Private and App Keys. You can replace them from an existing config by clicking the Replace Keys... button.

Clicking the Replace button will allow you to cut-n-paste values from an existing configuration into Jenkins. You can then validate the id and keys by clicking the the Validate Credential button.

Example Usage: Freestyle Project

For a Freestyle project the environmental variable injection is performed via a Build step.

In the Add build step dropdown, select Keeper Secrets Manager.

In the Credential dropdown select the Keeper Secrets Manager credential that was created in the prior steps.

Using Keeper Notation syntax, the environmental variable is magically replaced with the matching value from the record in the Keeper vault. You can reference any field within the Keeper vault secret such as login, password, custom field or filename.

Then select the destination for the secret. A secret can be placed into an environmental variable or a file within the build's workspace.

You can add multiple environmental variable to the Build step by clicking on "Add Secret" and populating the environmental variable and notation fields.

Keeper Notation Syntax

Use the Keeper notation format to select which record field to use as your secret. Keeper notation has the following format:

keeper://<Record UID>/field/<field name>

Where "Record UID" is the UID of the record which contains the secret credential as a field and "field name" is the field that credential is stored as, such as "password"

Here's an example: keeper://3FXqmP5nFKwju0H8pl0DmQ/field/password

The Record UID can be found in Keeper Commander or inside the Web Vault user interface.

Using Your Secrets

The populated environment variables will available to the following build steps. You can even add another Keeper Secrets Manager step and select secret from a different account or application.

You can use and view the environment variables in a Execute Shell step. For example:

#!/bin/bash

my_app --login "${MY_LOGIN}"
echo "My Login = ${MY_LOGIN}"

In the above the environmental variable MY_LOGIN will be passed a parameter to the application my_app, however the echo statement will result in the text "****" the console. Text based secrets are actively redacted in the console.

Example Usage: Pipeline Integration (Workflows)

The Keeper Secret Manager plugin can be used inside a Jenkinsfile using a step that has the label withKsm. Below is an example.

pipeline {
  agent any 
  stages {
    stage('Hello') {
      steps {
        withKsm(application: [
          [
            credentialsId: '5142ceb84e9b4a2a9179cc5b6fe2798b',
            secrets: [
              [destination: 'env', envVar: 'MY_LOGIN', filePath: '', 
                notation: '1adh_WZxtbbHWqf6IALMVg/field/login'],
              [destination: 'env', envVar: 'MY_SEC_PHONE_NUM', filePath: '', 
                notation: 'Atu8tVgMxpB-iO4xT-Vu3Q/custom_field/phone[1][number]'],
              [destination: 'file', envVar: '', filePath: 'img.png', 
                notation: 'V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png']
            ]
          ]  
        ]) {
          sh'''
              # Will be redacted in console  
              echo "MY_LOGIN = ${MY_LOGIN}"
              echo "MY_SEC_PHONE_NUM = ${MY_SEC_PHONE_NUM}"

              ./my/build/script --login  "${MY_LOGIN}" --phone "${MY_SEC_PHONE_NUM}"
              file img.png
          '''
        }
      }
    }
  }
}

The Keeper Secrets Manager snippet can be created using the Pipeline Syntax snipper editor inside of Jenkins. Select withKsm from the Sample Step dropdown, then add a Keeper Secrets Manager Application, which will allow you to select the credentials and add secrets.

When you are finished setting up your application, credentials, and secrets, you can click the Generate Pipeline Script to generate the withKsm block. This snippet can then be added to your Jenkinsfile.

The environmental variables containing the secrets are only accessible within the withKsm block where they are defined. Once you exit the block, the secrets are not accessible.

Keeper Connection Manager

Keeper Secrets Manager integration into Keeper Connection Manager for dynamic secrets retrieval

Features

  • Retrieve secrets from Keeper when launching Remote RDP, SSH, MySQL and other connections

  • Protect secret configuration settings in the Keeper Vault

  • Provide privileged sessions without exposing credentials to the end-user

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager <> Keeper Connection Manager integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Connection Manager integration accepts the Base64 format configuration

Installation

This integration securely retrieves secrets from Keeper for use in establishing remote connections via RDP, SSH, VNC, MySQL, K8s and other protocols.

Step by Step documentation for activating Keeper Secrets Manager with Keeper Connection Manager can be found at the link below:

LogoVault IntegrationKeeper Connection Manager

Kubernetes External Secrets Operator

Synchronize Secrets from Keeper Secrets Manager with the K8s External Secrets Operator

Overview

Kubernetes External Secrets Operator injects secrets into Kubernetes by synchronizing them from various external APIs. This guide primarily focuses on the setup process for External Secrets, facilitating the synchronization of secrets from your Keeper Vault into Kubernetes.

The External Operator documentation can be found at this link.

Features

  • Seamless synchronization of secrets from Keeper Vault into Kubernetes via External Secrets.

  • Real-time access to secrets from Keeper Vault across all pods.

Prerequisites

Before proceeding with the setup, ensure you have the following:

  • Keeper Secrets Manager (KSM) access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

    • Make sure you add the proper permissions to your device in order to be able to read and write secrets

  • An initialized Keeper Secrets Manager Configuration

  • The following commands installed:

    • helm - package manager for Kubernetes

    • kubectl - command line tool for Kubernetes

Setup

Install External Secrets With Helm

To install External Secrets with Helm, run the following commands:

helm repo add external-secrets https://charts.external-secrets.io

helm install external-secrets \
    external-secrets/external-secrets \
    -n external-secrets \
    --create-namespace

Create Kubernetes Secret to store Base64 KSM Config

After creating a Secrets Manager Configuration for your device, you will have a Base64 JSON string that contains connection tokens, encryption keys, identifiers and domain information used to authenticate and decrypt data from the Keeper Secrets Manager APIs.

The Base64 JSON config string will be set by External Secrets to authenticate against Keeper Security and defined in a regular Kubernetes Secret.

Invoking the following command will create a Kubernetes Secret which is used to authenticate to Keeper Secrets Manager:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: ksm-config-secret # name of the k8s Secret where KSM config is stored
type: Opaque
data:
  ksm_config: "[REPLACE WITH YOUR BASE64 JSON string]"
EOF

Note: Lines 2-8 in the above code snippet can be stored in a YAML file and applied with the command kubectl apply. For example, you can store lines 2-8 in secrets.yaml and execute the following:

kubectl apply -f secret.yaml

Create SecretStore

After creating a Kubernetes Secret with ksm_config defined to your Base64 JSON string, you can now create your SecretStore.

Invoking the following command will create your SecretStore:

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1beta1   
kind: SecretStore
metadata:
  name: my-external-secrets-secretstore   # name of the SecretStore where retrieved secrets will be stored once fetched from Keeper Secrets Manager (KSM)
spec:
  provider:
    keepersecurity:                       # name of the SecretStore provider, in this case KeeperSecurity
      authRef:
        name: ksm-config-secret           # name of the k8s Secret where KSM config is stored
        key: ksm_config                   # key in the k8s Secret where KSM config is stored
      folderID: "[SHARED FOLDER UID]"     # UID of the shared folder in KeeperSecurity where the records 
                                          #   are stored. Make sure the folder is shared into the KSM Application
EOF

In the above code snippet, define folderID with the UID of the shared folder where the records are stored in your Vault

In case of a ClusterSecretStore, Be sure to provide namespace for SecretAccessKeyRef with the namespace of the secret that we just created.

Note: Lines 2-13 in the above code snippet can be stored in a YAML file and applied with the command kubectl apply. For example, you can store lines 2-13 in secretstore.yaml and execute the following:

kubectl apply -f secretstore.yaml

Create ExternalSecret

Next, you need to create your ExternalSecret.

The following code snippet will create your External Secret and store the values of the login & password field for the specified record into the Kubernetes Secret. These fields are defined in the target.template.data section and refreshed every 30 seconds. For a full list of supported fields, visit this page.

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
 name: ksm-external-secret
spec:
 refreshInterval: 12h               # rate how often SecretManager pulls KeeperSecurity. 
                                    #   In this case every 12 hours, for the example. 
                                    #   We recommend this value to be 12h or more.
 secretStoreRef:                    # reference to the SecretStore defined above to authenticate against Keeper Security
   kind: SecretStore                # tells External Secrets the type of the secret store, should be same as the one defined above
   name: my-external-secrets-secretstore  

 dataFrom:                          # tells External Secrets which record to use to fetch from Keeper Secrets Manager (KSM)
   - extract:
       key: "[RECORD UID]"          # UID of the record in Keeper where the secrets are going to be fetched from
 target:                            # tells External Secrets the target location where to store the secrets once fetched from Keeper Security
   name: my-external-secrets-values # name of the k8s Secret to be created
   creationPolicy: Owner            # tells External Secrets to create the k8s Secret if it doesn't exist
   template:
     engineVersion: v2          
     data:
       username: "{{ .login }}"     # tells External Secrets to store the value of 
                                    # the login field in Keeper Security into the k8s Secret under the key username
       password: "{{ .password }}"  # tells External Secrets to store the value of 
                                    # the password field in Keeper Security into the k8s Secret under the key password
       name: "{{  (fromJson .name).first }} {{  (fromJson .name).middle }} {{  (fromJson .name).last }}" # decode json string into vars
EOF

In the above code snippet, replace "[RECORD UID]" with the UID of your desired record

For complex types, like name, phone, bankAccount, which does not match with a single string value, external secrets will return the complete JSON string. Use the JSON template functions to decode.

Note: Lines 2-27 in the above code snippet can be stored in a YAML file and applied with the command kubectl apply. For example, you can store lines 2-27 in externalsecret.yaml and execute the following:

kubectl apply -f externalsecret.yaml

Behavior

  • How a Record is equated to an ExternalSecret:

    • remoteRef.key is equated to a Record's ID

    • remoteRef.property is equated to one of the following options:

      • Fields: Record's field's Type

      • CustomFields: Record's field's Label

      • Files: Record's file's Name

      • If empty, defaults to the complete Record in JSON format

    • remoteRef.version is currently not supported.

  • dataFrom:

    • find.path is currently not supported.

    • find.name.regexp is equated to one of the following options:

      • Fields: Record's field's Type

      • CustomFields: Record's field's Label

      • Files: Record's file's Name

    • find.tags are not supported at this time.

Limitations

There are some limitations using this provider.

  • Keeper Secret Manager does not work with legacy non-typed records

  • Using tags find.tags is not supported by KSM

  • Using path find.path is not supported at the moment

Push Secrets

Push Secret will only work with a custom KeeperSecurity Record type ExternalSecrets

Behavior

  • selector:

  • secret.name: name of the kubernetes secret to be pushed

  • data.match:

  • secretKey: key on the selected secret to be pushed

  • remoteRef.remoteKey: Secret and key to be created on the remote provider

    • Format: SecretName/SecretKey

Create PushSecret

To create a Keeper Security record from Kubernetes a Kind=PushSecret is needed.

kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: example
spec:
  secretStoreRefs:
    - name: keeper
      kind: SecretStore
  refreshInterval: "1h"
  deletionPolicy: Delete
  selector:
    secret:
      name: secret-name # k8s secret to be pushed
  data:
    - match:
        secretKey: secret-key # k8s key within the secret to be pushed
        remoteRef:
          remoteKey: remote-secret-name/remote-secret-key # This will create a record called "remote-secret-name" with a key "remote-secret-key"
EOF

Note: Lines 2-19 in the above code snippet can be stored in a YAML file and applied with the command kubectl apply. For example, you can store lines 2-19 in pushsecret.yaml and execute the following:

kubectl apply -f pushsecret.yaml

Make sure there's only one record with the title remote-secret-name in the KSM Application in use.

Limitations

  • Only possible to push one key per secret at the moment

  • If the record with the selected name exists but the key does not exists the record can not be updated.

Verifying Setup

After setting up your Kubernetes Secret, SecretStore, and ExternalSecret, you can extract secrets with the command kubectl get secrets

In the above code snippets, the name of the secret is my-external-secrets-values and we store the following record values:

data:
       username: "{{ .login }}"                                      
       password: "{{ .password }}"

To get the login and password values, invoke the following command:

$ kubectl get secret my-external-secrets-values -o jsonpath="{.data}"
{"password":"a2lsbCB5b3U=","username":"SSB3aWxs"}

The above response is encoded, to decode, invoke the following:

$ kubectl get secret my-external-secrets-values -o jsonpath="{.data.password}" | base64 --decode
pAs$w0rd

Conclusion

In conclusion, this guide has detailed a step-by-step process for integrating the Keeper Secrets Manager with Kubernetes via the Kubernetes External Secrets Operator. By following these steps, you'll be able to seamlessly synchronize your secrets stored in Keeper Vault into your Kubernetes environment. This not only provides a secure method to manage your secrets but also facilitates real-time access across all your pods.

The processes outlined, including setting up the External Secrets operator, creating a Kubernetes Secret, SecretStore, and ExternalSecret, are key to this integration. Upon successful setup, the provided commands allow you to verify the integration and retrieve stored secrets effortlessly.

The integration of Keeper Secrets Manager with Kubernetes enhances the security infrastructure of your applications running in the Kubernetes environment. It provides a solid foundation for managing your secrets, thereby improving overall operational efficiency and security posture.

Remember to replace all placeholders in the command snippets with your specific information, and don't hesitate to refer back to this guide anytime you need to set up or manage your External Secrets in Kubernetes.

Kubernetes (alternative)

Keeper Secrets Manager integration into Kubernetes for dynamic secrets retrieval

We recommend using the Kubernetes External Secrets Operator integration for most use cases. This document describes an alternate method of integration which does not utilize the External Secrets Operator.

Features

  • Retrieve secrets from the Keeper Vault within the Kubernetes

  • Access secrets from the Keeper Vault in real-time across all pods

  • Copy secure file attachments from the Keeper Vault to the local filesystem

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Kubernetes integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

About

Keeper Secrets Manager can be integrated into your K8s cluster for accessing Keeper secrets in real-time across all pods.

Setup

Create a Secrets Manager Configuration

Using Commander, create a Secrets Manager device configuration for Kubernetes. Note that this configuration is not IP locked and it is pre-initialized.

Create the configuration in Commander using this command:

secrets-manager client add --app <APP NAME> --unlock-ip --config-init k8s

Example:

My Vault> sm client add --app MyAdd --unlock-ip --config-init k8s

Successfully generated Client Device
====================================

Initialized Config:

apiVersion: v1
data:
  config: ewog2N...ICIxMCIKfQ==
metadata:
  name: ksm-config
  namespace: default
type: Opaque

IP Lock: Disabled
Token Expires On: 2021-10-13 12:45:45
App Access Expires on: Never

In the example above, copy lines 8 through 14 and place them into a file called secret.yaml. Then, If you are using a machine with kubectl installed and you have access to your cluster, add the KSM SDK config to your Kubernetes secrets.

$ kubectl apply -f secret.yaml

For more information on creating Secrets Manger configurations, see the Configuration Documentation

Alternate Method: One Time Access Token and KSM CLI

Alternatively, you can create a configuration by generating a One Time Access Token with Commander (or the Vault UI) and then using the Keeper Secret Manager CLI to create a configuration as demonstrated below (replace XX:XXX) with the One Time Access Token.

$ ksm init k8s XX:XXX

apiVersion: v1
data:
  config: ewog2N[...]ICIxMCIKfQ==
kind: Secret
metadata:
  name: ksm-config
  namespace: default
type: Opaque

If you are using a machine with kubectl installed and you have access to your cluster, the parameter --apply can be set to automatically add the KSM SDK config to your Kubernetes secrets.

The output of redeeming the token can be piped to a file and then applied via kubectl. For example:

$ ksm init k8s XX:XXX > secret.yaml
$ kubectl apply -f secret.yaml
secret/ksm-config created

Using the KSM Config

The KSM config can be pulled into your K8s containers using secrets.

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: my_container:XXXXX
    env:
      - name: KSM_CONFIG
        valueFrom:
          secretKeyRef:
            name: ksm-config
            key: config
  restartPolicy: Never

At runtime, the Keeper Developer SDKs running in the K8s cluster will use the environment variable KSM_CONFIG to retrieve the device configuration and communicate with the Keeper Vault.

Examples

Example 1 - Custom App using SDK

Below is a simple example that will generate a deployment and service that displays database secrets via a web application. This example uses the Keeper Python Developer SDK for the web application. The SDK will get its configuration from a Kubernetes secret and then retrieve PostgreSQL database record information from the Keeper vault.

From the Keeper Vault, a "Database" record type is created using the following information.

Now let's create our web application. The web page can be created using any of the Developer SDKs. For this example, it will being using the Python SDK. A simple Flask application with one endpoint will display the HTML that contains the Vault record secrets. The secrets are retrieved using the Keeper Notation syntax.

from flask import Flask
from keeper_secrets_manager_core import SecretsManager
import os

app = Flask(__name__)

@app.route("/")
def hello_world():
    sm = SecretsManager()
    return """
<h1>Database</h1>
<ul>
    <li>Type: {}</li>
    <li>Host: {}</li>
    <li>Port: {}</li>
    <li>Login: {}</li>
    <li>Password: {}</li>
</ul>
""".format(
       sm.get_notation(os.environ.get("DB_TYPE")),
       sm.get_notation(os.environ.get("DB_HOST")),
       sm.get_notation(os.environ.get("DB_PORT")),
       sm.get_notation(os.environ.get("DB_LOGIN")),
       sm.get_notation(os.environ.get("DB_PASS")))

The next part is creating a Dockerfile. The Dockerfile below is based off of the Python Debian images from Docker Hub.

The Python SDK uses the cryptography module. This module requires the language Rust to be installed. Other Docker Hub images may provide Rust pre-installed.

FROM python:3.10.0-slim-bullseye
RUN apt-get update \
    && apt-get install -y gcc make libffi-dev curl libssl-dev \
    && apt-get clean
RUN pip3 install --upgrade pip wheel

# cryptology requires Rust to build
RUN curl https://sh.rustup.rs -sSf > /tmp/rust.sh \
    && chmod a+x /tmp/rust.sh \
    && /tmp/rust.sh -y
ENV PATH $PATH:/root/.cargo/bin

RUN pip3 install \
    flask \
    keeper-secrets-manager-core

RUN groupadd -g 5000 demo
RUN useradd -g demo demo

# Copy our application into the image
COPY demo.py /demo.py

USER demo

ENV FLASK_APP demo

EXPOSE 5000
CMD ["flask", "run"]

Next we will build a Docker image named ksm_demo.

$ docker build -t ksm_demo .

Assuming there is access to the Kubernetes cluster, the config can be generated from the One Time Access Token and automatically applied.

$ ksm init k8s --apply XX:XXXXXXXXXXX
secret/ksm-config created
Created secret for KSM config.

You can see the secret entry when you enter kubectl get secret.

$ kubectl get secret ksm-config
NAME         TYPE     DATA   AGE
ksm-config   Opaque   1      55s

You can then make a deployment and service for the ksm_demo Docker image. This example is going to name the file ksm_demo.yaml.

Defining which secrets you need, and the config for the SDK, happen in the env section in the list of containers. In this section the KSM_CONFIG environmental variable is defined to get it's value from the ksm-config Kubernetes secret, specifically the config key of the secret.

The other environmental variables are just list of name/values. The value is Keeper Notation which the web application will send to the notation retrieval method of the SDK.

The second record in the ksm_demo.yaml file is the Service definition. This can be changed to whatever works with your Kubernetes cluster. In our example, it uses an external IP address. It's safe to use one of your Kubernetes nodes IP address, 10.0.1.18 for the example.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ksm-demo-deployment
  labels:
    app: ksm-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ksm-demo
  template:
    metadata:
      labels:
        app: ksm-demo
    spec:
      nodeSelector:
        kubernetes.io/hostname: work
      dnsPolicy: "None"
      dnsConfig:
        nameservers:
          - 10.0.1.207
          - 1.1.1.1
      containers:
        - name: ksm-demo
          image: ksm_demo:latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5000
              protocol: TCP
          env:
            - name: KSM_CONFIG
              valueFrom:
                secretKeyRef:
                  name: ksm-config
                  key: config
            - name: DB_TYPE
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/Type"
            - name: DB_HOST
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/host[hostName]"
            - name: DB_PORT
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/host[port]"
            - name: DB_LOGIN
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/login"
            - name: DB_PASS
              value: "keeper://IUCvqyWcx7sG-BGIK1R9-g/field/password"
---   
apiVersion: v1
kind: Service
metadata:
  name: ksm-demo-service
spec:
  ports:
    - name: http
      port: 5000
      targetPort: 5000
      protocol: TCP
  selector:
    app: ksm-demo
  externalIPs:
    - 10.0.1.18

At this point the deployment and service are ready to be applied.

$ kubectl apply -f ksm_demo.yaml
deployment/ksm-demo-deployment created
service/ksm-demo-service created

Wait until your deployment is ready. Either monitor it via the command line or Kubernetes Dashboard.

$ kubectl get deployment ksm-demo-deployment
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
ksm-demo-deployment   1/1     1            1           46m

$ kubectl get svc ksm-demo-service
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
ksm-demo-service   ClusterIP   10.107.91.89   10.0.1.18     5000/TCP   56m

Finally, use a web browser and go to the external IP address, port 5000, and you will see the Keeper vault record database secrets.

Example Web Application displaying Keeper secrets

Example 2 - NGINX SSL certificates

In this example a pod will be created that contains the stock NGINX docker image and SSL certificates retrieved from the Keeper Vault.

A Login record is created in the vault to hold the SSL certificate, private key, and certificate password.

A one time token is generated and added to the Kubernetes ConfigMap.

$ ksm init k8s XX:XXX > secret.yaml
$ kubectl apply -f secret.yaml
secret/ksm-config created

The example website is simply an index HTML page. The HTML can be stored in the ConfigMap and mounted in to the document root directory.

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-html-config
  namespace: default
  labels:
    app: nginx
data:
  index.html: |
    <html>
      <head>
         <title>Nginx Test Page</title>
      </head>
      <body>
        <h1>Hello From Keeper Secrets Manager!</h1>
      </body>
    </html>

The default.conf will be overwritten by our example. The certificate, key, and password will be placed in to the /etc/keys directory. For non-interactive startup, NGINX requires the certificate password be placed in a file and ssl_password_file to be included in the server configuration.

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: default
  labels:
    app: nginx
data:
  default.conf: |
    server {
      listen 80 default;
      server_name localhost;
      location / {
        root /var/www/nginx-default;
        index index.html index.htm;
      }
    }
    server {
      listen 443 ssl;
      server_name localhost;
      ssl_certificate /etc/keys/example.com.crt;
      ssl_certificate_key /etc/keys/example.com.key;
      ssl_password_file /etc/keys/global.pass;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers HIGH:!aNULL:!MD5;
      location / {
        root /var/www/nginx-default;
        index index.html index.htm;
      }
    }

The deployment for this example looks like the following:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      initContainers:
        - name: ksm
          image: keeper/keeper-secrets-manager-writer:latest
          env:
            - name: KSM_CONFIG
              valueFrom:
                secretKeyRef:
                  name: ksm-config
                  key: config
            - name: SECRETS
              value: |
                5x0v0VFwYj2VvuhamrJhzQ/field/password > file:/etc/keys/global.pass
                5x0v0VFwYj2VvuhamrJhzQ/file/example.com.crt > file:/etc/keys/example.com.crt
                5x0v0VFwYj2VvuhamrJhzQ/file/example.com.key > file:/etc/keys/example.com.key
          volumeMounts:
            - mountPath: "/etc/keys"
              name: keys-volume
      containers:
        - name: nginx
          image: nginx:1.21.4-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              protocol: TCP
            - containerPort: 443
              protocol: TCP
          volumeMounts:
            - mountPath: "/etc/keys"
              name: keys-volume
            - mountPath: "/etc/nginx/conf.d/default.conf"
              name: nginx-config-file
              subPath: default.conf
            - mountPath: "/var/www/nginx-default/index.html"
              name: nginx-html-file
              subPath: index.html
      volumes:
        - name: keys-volume
          emptyDir: {}
        - name: nginx-config-file
          configMap:
            name: nginx-config
        - name: nginx-html-file
          configMap:
            name: nginx-html-config
      imagePullSecrets:
        - name: my-docker-hub-secrets

The docker image keeper/keeper-secrets-manager-writer is used for an initialization container. The container will retrieve the secrets and write them to disk so they can be used by NGINX. The secrets are written to the pod's emptyDir volume, mounted to /etc/keys. This directory will be removed when the pod is deleted.

Documentation for the Keeper Secrets Manager Writer can be found here.

The main container will also mount the pod's emptyDir volume to /etc/keys. And will also mount the default.conf into /etc/nginx/conf.d and the index.html file into the document root for the server.

The last part is to create a service to access NGINX as shown below.

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
    - name: http
      port: 80
      targetPort:  80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app: nginx
  externalIPs:
    - XXX.XXX.XXX.XX

The service can be tested by going to the external IP via https (ie https://XXX.XXX.XXX.XXX). Notice the lock in the address bar indicates the certificate is valid.

External Secrets

External Secrets is a Kubernetes operator that synchronizes secrets from External APIs and injects them into Kubernetes. For more information on how to setup External Secrets to synchronize secrets from your Keeper Vault into Kubernetes, visit the following:

Kubernetes External Secrets Operator

Next Steps

At this point, you can now integrate Keeper Secrets Manager into your K8s deployments using any of the Secrets Manager SDKs.

Linux Keyring

Store and Retrieve Secrets from the Linux Keyring

Overview

Keyring is a Linux security feature that stores sensitive information, such as passwords and secrets, and allows applications to securely access it.

Keeper provides a utility, the Linux Keyring Utility, that interacts with the native Linux APIs to store and retrieve secrets from the Keyring using the Secret Service API. This utility can be used by any integration, plugin, or code base to store and retrieve credentials, secrets, and passwords in any Linux Keyring simply and natively.

The code base for the Linux Keyring Utility can be found here:

LogoGitHub - Keeper-Security/linux-keyring-utility: A utility for natively interacting with the Linux KeyringGitHub

The binary needed to use the above utility can be found here:

LogoReleases · Keeper-Security/linux-keyring-utilityGitHub

To use the Linux Keyring Utility, you can either

  • deploy the pre-built binary from the releases page

  • or import it into your code base.

Both use cases are covered below.

Linux Keyring Utility

The Linux Keyring Utility gets and sets secrets in a Linux Keyring using the D-Bus Secret Service.

It has been tested with GNOME Keyring and KDE Wallet Manager. It should work with any implementation of the D-Bus Secrets Service.

Interface

There are two packages, dbus_secrets and secret_collection. The secret_collection object uses the functions in dbus_secrets. It unifies the D-Bus Connection, Session and Collection Service objects to offer a simple get/set/delete interface that the CLI uses.

Usage - Importing it into your codebase

The Go Language API has offers Get(), Set() and Delete() methods. The first two accept and return string data.

Example (get)

package main

import (
    "os"
    sc "github.com/Keeper-Security/linux-keyring-utility/pkg/secret_collection"
)

func doit() {
    if collection, err := sc.DefaultCollection(); err == nil {
        if err := collection.Unlock(); err == nil {
            if secret, err := collection.Get("myapp", "mysecret"); err == nil {
                print(string(secret))
                os.Exit(0)
            }
        }
    }
    os.Exit(1)
}

The .DefaultCollection() returns whatever collection the default alias refers to. It will generate an error if the default alias is not set. It usually points to the login keyring. Most Linux Keyring interfaces allow the user to set it.

The .NamedCollection(string) method provides access to collections by name.

Example (set)

Set takes the data as a parameter and only returns an error or nil on success. It does not restrict the content or length of the secret data.

if err := collection.Set("myapp", "mysecret", "mysecretdata"); err == nil {
    // success
}

Usage - Binary Interface (CLI)

The Linux binary supports three subcommands:

  1. get

  2. set

  3. del

Get and del require one parameter; name, which is the secret Label in D-Bus API terms.

Del accepts one or more secret labels and deletes all of them. If it generates an error it will stop.

Set also requires the data as a single string in the second parameter. For example, set foo bar baz will generate an error but set foo 'bar baz' will work. If the string is - then the string is read from standard input.

Base64 encoding

Get and set take a -b or --base64 flag that handles base64 automatically. If used, Set will encode the input before storing it and/or get will decode it before printing.

Note that calling get -b on a secret that is not base64 encoded secret will generate an error.

Examples

# set has no output
lkru set root_cred '{
    "username": "root"
    "password": "rand0m."
}'
# get prints (to stdout) whatever was set
lku get root_cred
{
    "username": "root"
    "password": "rand0m."
}
lkru set -b root_cred2 '{"username": "gollum", "password": "MyPrecious"}'
lkru get root_cred2
eyJ1c2VybmFtZSI6ICJnb2xsdW0iLCAicGFzc3dvcmQiOiAiTXlQcmVjaW91cyJ9
lkru get -b root_cred2
{"username": "gollum", "password": "MyPrecious"}
cat ./good_cred.json | lkru set -b root_cred3 -
lkru get root_cred3
ewogICJ1c2VybmFtZSI6ICJhZGFtIiwKICAicGFzc3dvcmQiOiAicGFzc3dvcmQxMjMuIgp9

Errors

Error output goes to stderr so adding 2>/dev/null to the end of a command will suppress it.

No keyring

The login collection does not exist because the keyring does not exist. KDE may create kdewallet instead of login like GNOME.

Unable to get secret 'test_cred': Unable to retrieve secret 'test_cred' for application 'lkru' from collection '/org/freedesktop/secrets/collection/login': Object does not exist at path “/org/freedesktop/secrets/collection/login”

No matching secret

A secret may not be returned even though a secret with the same label exists. If the secret was not created with lkru, it may not have the same attributes. Namely 'Agent', 'Application', and 'Id'.

Unable to get secret 'test_cred': Unable to retrieve secret 'test_cred' for application 'lkru' from collection '/org/freedesktop/secrets/aliases/default': org.freedesktop.Secret.Collection.SearchItems returned nothing

No D-Bus Session

There may not be a D-Bus Session to host the Secret Service. This happens when the user is not logged into the GUI.

Unable to get the default keyring: Unable to open a D-Bus session: The name org.freedesktop.secrets was not provided by any .service files

No D-Bus

The system may not host D-Bus. Several lightweight linux distributions ship without it by default.

Unable to get the default keyring: Unable to connect to the D-Bus Session Bus: exec: "dbus-launch": executable file not found in $PATH

Model Context Protocol (MCP) for AI Agents (Docker)

Integrate Keeper Secrets Manager into AI agents using Docker

To utilize AI Agent integrations with Keeper Secrets Manager (KSM), your role must have the enforcement setting “Can create applications and manage secrets” enabled.

By enabling this feature, you authorize integration between Keeper and third-party AI tools or services. Keeper maintains its Zero-Trust architecture and does not access or process your vault records.

However, any data shared with third-party tools will be governed by those tools’ security, privacy, and compliance practices - not Keeper’s. You are solely responsible for configuring, managing, and auditing these integrations in accordance with your organization’s internal policies and applicable regulations.

To reduce exposure, access granted to AI Agents should be limited to only the minimum necessary folders in the Keeper Vault required to accomplish your specific use case.

AI Agent Integration with Model Context Protocol (MCP)

Keeper Secrets Manager works with AI agents through the Model Context Protocol (MCP), enabling AI Agents to securely interact with specific vault folders. This integration provides a zero-trust architecture where AI agents are explicitly allowed to access designated information from the Keeper Vault.

The Model Context Protocol integration acts as a secure bridge between AI assistants and Keeper Secrets Manager. It allows AI tools to help you manage secrets while maintaining the highest security standards through human-in-the-loop confirmations for sensitive operations.

LogoGitHub - Keeper-Security/keeper-mcp-golang-docker: Keeper Secrets Manager - MCP (Model Context Protocol) server implementationGitHub

Key Benefits

Zero Trust Architecture: AI agents are assigned specific folders in the vault Human-in-the-Loop: Confirmation prompts for sensitive operations Enterprise Ready: Comprehensive audit logging and compliance features Multi-Platform: Works on Linux, macOS, and Windows Docker Native: Easy deployment with container support

What Can AI Assistants Do?

With KSM MCP integration, AI assistants can help you:

Secret Operations

List secrets - Browse your accessible secrets Search secrets - Find secrets by title, URL, username, or other fields Retrieve secrets - Get specific secret values (with confirmation for unmasked data) Create secrets - Generate new secret entries Update secrets - Modify existing secret information Delete secrets - Remove secrets (with confirmation)

File Management

List attachments - View file attachments on secrets Upload files - Add file attachments to secrets Download files - Retrieve file attachments Delete files - Remove file attachments

Utilities

Generate passwords - Create secure passwords with customizable parameters Get TOTP codes - Retrieve current time-based one-time passwords Execute KSM notation queries - Use Keeper's notation system for complex operations Health checks - Monitor server status and connectivity

Setup and Installation

(1) Create Secrets Manager Application

From Keeper Secrets Manager, create an Application or use an existing application.

Create an Application and assign folders

(2) Create a Device Token

Discard the first Device token, and click on "Add Device" to generate a new Base64 configuration that will be provided to your AI agent.

Generate Base64 Token

(3) Register the MCP server

From your AI Agent configuration screen, register the Keeper Secrets Manager MCP server.

The specific details vary between AI agent applications. In Claude Desktop, this can be set up by opening Settings > Developer and then clicking Edit Config. Add the "ksm" server to this file, making sure to include the Base 64 configuration string generated in step 2.

{
  "mcpServers": {
    "ksm": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "KSM_CONFIG_BASE64=<KSM_CONFIG_BASE64_HERE>",
        "-e", "KSM_MCP_PROFILE=production",
        "-e", "KSM_MCP_BATCH_MODE=true",
        "-e", "KSM_MCP_LOG_LEVEL=error",
        "-v", "ksm-mcp-data:/home/ksm/.keeper/ksm-mcp",
        "keeper/keeper-mcp-server:latest"
      ]
    }
  }
}
Claude Desktop Integration

Once this is set, you can begin interacting with the Keeper Secrets Manager MCP server.

Interacting with the KSM MCP Server
Generating a Password

Logs and event reporting are available inside the device logs screen and the Keeper Admin Console screens.

Event logs

For additional setup details, see: https://github.com/Keeper-Security/keeper-mcp-golang-docker

Model Context Protocol (MCP) for AI Agents (Node)

Integrate Keeper Secrets Manager into AI agents using Node

To utilize AI Agent integrations with Keeper Secrets Manager (KSM), your role must have the enforcement setting "Can create applications and manage secrets" enabled.

By enabling this feature, you authorize integration between Keeper and third-party AI tools or services. Keeper maintains its Zero-Trust architecture and does not access or process your vault records.

However, any data shared with third-party tools will be governed by those tools’ security, privacy, and compliance practices - not Keeper’s. You are solely responsible for configuring, managing, and auditing these integrations in accordance with your organization’s internal policies and applicable regulations.

To reduce exposure, access granted to AI Agents should be limited to only the minimum necessary folders in the Keeper Vault required to accomplish your specific use case.

AI Agent Integration with Model Context Protocol (MCP)

Keeper Secrets Manager works with AI agents through the Model Context Protocol (MCP), enabling AI Agents to securely interact with specific vault folders. This integration provides a zero-trust architecture where AI agents are explicitly allowed to access designated information from the Keeper Vault.

The Model Context Protocol integration acts as a secure bridge between AI assistants and Keeper Secrets Manager. It allows AI tools to help you manage secrets while maintaining the highest security standards through human-in-the-loop confirmations for sensitive operations.

LogoGitHub - Keeper-Security/keeper-mcp-node: MCP implementation using Keeper Secrets Manager and NodeGitHub

Key Benefits

Zero Trust Architecture: AI agents are assigned specific folders in the vault Human-in-the-Loop: Confirmation prompts for sensitive operations Enterprise Ready: Comprehensive audit logging and compliance features Multi-Platform: Works on Linux, macOS, and Windows

What Can AI Assistants Do?

With KSM MCP integration, AI assistants can help you:

Secret Operations

List secrets - Browse your accessible secrets Search secrets - Find secrets by title, URL, username, or other fields Retrieve secrets - Get specific secret values (with confirmation for unmasked data) Create secrets - Generate new secret entries Update secrets - Modify existing secret information Delete secrets - Remove secrets (with confirmation)

File Management

List attachments - View file attachments on secrets Upload files - Add file attachments to secrets Download files - Retrieve file attachments Delete files - Remove file attachments

Utilities

Generate passwords - Create secure passwords with customizable parameters Get TOTP codes - Retrieve current time-based one-time passwords Execute KSM notation queries - Use Keeper's notation system for complex operations Health checks - Monitor server status and connectivity

Setup and Installation

(1) Create Secrets Manager Application

From Keeper Secrets Manager, create an Application or use an existing application.

Create an Application and assign folders

(2) Create a Device Token

Discard the first Device token, and click on "Add Device" to generate a new Base64 configuration that will be provided to your AI agent.

Generate Base64 Token

(3) Configure the MCP Server

You have two options for providing your Keeper configuration:

Option A: Configuration File (Recommended)

Place your downloaded configuration file in one of these locations:

  • ~/.keeper/ksm-config.json (recommended)

  • ./ksm-config.json (in the current directory)

Option B: One-Time Token

If you have a one-time token instead:

export KSM_TOKEN="US:YOUR_ONE_TIME_TOKEN_HERE"

The server will use this token to generate and save a configuration file automatically.

(4) Test the Server

Run the server directly to test:

npm start

You should see: Keeper MCP server is running

Usage with MCP Clients

Claude Desktop

Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "keeper": {
      "command": "node",
      "args": ["/path/to/keeper-mcp-node/dist/index.js"]
    }
  }
}

Postman

  1. In Postman, go to the API Network tab

  2. Create or select an MCP request

  3. Configure the stdio connection:

    • Command: node

    • Arguments: /path/to/keeper-mcp-node/dist/index.js

Other MCP Clients

The server communicates via stdio, so you can integrate it with any MCP-compatible client by running:

node /path/to/keeper-mcp-node/dist/index.js

Available Tools

Secret Operations

ksm_list_secrets

List all secrets accessible to your application (metadata only)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_list_secrets",
    "arguments": {}
  }
}

Response:

[
  {
    "uid": "XXXXXXXXXXXXXXXXXXXXXX",
    "title": "My Secret",
    "type": "login"
  }
]

ksm_get_secret

Retrieve a complete secret by UID or title (sensitive fields masked by default)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_get_secret",
    "arguments": {
      "identifier": "My Secret",
      "unmask": false
    }
  }
}

ksm_search_secrets

Search for secrets by title, notes, or other field content

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_search_secrets",
    "arguments": {
      "query": "database"
    }
  }
}

ksm_create_secret

Create a new secret in Keeper Secrets Manager (requires confirmation)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_create_secret",
    "arguments": {
      "title": "New Database Credentials",
      "type": "login",
      "fields": {
        "login": "admin",
        "password": "secure_password",
        "url": "https://db.example.com"
      },
      "notes": "Production database",
      "folderId": "FOLDER_UID"
    }
  }
}

ksm_update_secret

Update an existing secret (requires confirmation)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_update_secret",
    "arguments": {
      "identifier": "My Secret",
      "updates": {
        "title": "Updated Title",
        "fields": {
          "password": "new_password"
        }
      }
    }
  }
}

ksm_delete_secret

Delete a secret from Keeper Secrets Manager (requires confirmation)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_delete_secret",
    "arguments": {
      "identifier": "My Secret"
    }
  }
}

ksm_get_field

Get a specific field value from a secret

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_get_field",
    "arguments": {
      "identifier": "My Secret",
      "field": "password"
    }
  }
}

Common field names:

  • password - The password field

  • login - Username/email

  • url - Website URL

  • Custom field labels

Folder Operations

ksm_list_folders

List all accessible folders in Keeper Secrets Manager

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_list_folders",
    "arguments": {}
  }
}

ksm_create_folder

Create a new folder (requires confirmation; must specify a parent shared folder)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_create_folder",
    "arguments": {
      "name": "Development Secrets",
      "parentFolderId": "PARENT_FOLDER_UID"
    }
  }
}

ksm_delete_folder

Delete a folder (requires confirmation)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_delete_folder",
    "arguments": {
      "folderId": "FOLDER_UID",
      "force": false
    }
  }
}

File Management

ksm_upload_file

Upload a file attachment to a secret (requires confirmation)

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_upload_file",
    "arguments": {
      "identifier": "My Secret",
      "filePath": "/path/to/certificate.pem",
      "fileName": "server-cert.pem"
    }
  }
}

ksm_download_file

Download a file attachment from a secret

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_download_file",
    "arguments": {
      "identifier": "My Secret",
      "fileId": "certificate.pem",
      "outputPath": "/tmp/downloaded-cert.pem"
    }
  }
}

Utilities

ksm_generate_password

Generate a secure password

Can optionally save to a new secret without exposing it to the AI

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_generate_password",
    "arguments": {
      "length": 24,
      "includeUppercase": true,
      "includeLowercase": true,
      "includeNumbers": true,
      "includeSpecial": true,
      "saveToSecret": {
        "title": "Generated API Key",
        "login": "api-user",
        "url": "https://api.example.com",
        "notes": "Auto-generated API key"
      }
    }
  }
}

ksm_get_totp_code

Get the current TOTP code for a secret that has TOTP configured

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_get_totp_code",
    "arguments": {
      "identifier": "My 2FA Secret"
    }
  }
}

ksm_get_server_version

Get the current version of the KSM MCP server

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_get_server_version",
    "arguments": {}
  }
}

ksm_health_check

Check the operational status of the MCP server and its connection to KSM

Request:

{
  "method": "tools/call",
  "params": {
    "name": "ksm_health_check",
    "arguments": {}
  }
}

Troubleshooting

Error: No Keeper Secrets Manager configuration found

  • Ensure your configuration file is in one of the supported locations

  • Check that the file has proper JSON formatting

  • Verify file permissions (should be readable by your user)

Error: Failed to initialize KSM

  • Verify your configuration file contains all required fields

  • Check that your application has access to the shared folders/secrets

  • Ensure your device hasn't been revoked in Keeper

Connection Issues

  • Verify you have internet connectivity

  • Check if your organization has IP restrictions enabled

  • Ensure your Keeper subscription includes Secrets Manager


For additional setup details, see: https://github.com/Keeper-Security/keeper-mcp-node/

Octopus Deploy

Keeper Secrets Manager Step Template for accessing secrets in Octopus Deploy

Keeper Secrets Manager and Octopus Deploy
Octopus Deploy Integration with Keeper Secrets Manager

Features

  • Retrieve secrets from the Keeper Vault to use in Octopus Deploy Library

  • Inject credentials directly into Octopus Deploy projects

  • Get files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Octopus Deploy integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Octopus Deploy integration accepts Base 64 format configurations

About

The Keeper Octopus Deploy Step Template utilizes Keeper Secrets Manager to provide access to secret credentials saved in the Keeper Vault. The script allows for injecting secrets directly into Octopus Deploy projects securely using Keeper's zero-knowledge infrastructure.

Installation

Community Step Template

To use the step template directly from Community Step Templates: Navigate: Library > Step Templates > Community Step Templates > Browse Library Search: "Keeper Secrets Manager - Retrieve Secrets" > Install > Save

Custom Step Template

To add as a Custom Step Template: Navigate: Library > Step Templates > Custom Step Templates > Import Paste the JSON obtained from community contributed templates library

Step Configuration

Settings

Name: Keeper Secrets Manager - Retrieve Secrets Description: This step retrieves one or more secrets from a Keeper Vault and creates sensitive output variables for each value retrieved. These values can be used in other steps in your deployment or runbook process. You can retrieve secrets using Keeper Notation URIs, and you can choose a custom output variable name for each secret. Required:

  • A Keeper Secrets Manager application with permissions to retrieve secrets from the Keeper Vault.

  • The SecretManagement.Keeper.Extension PowerShell module installed on the target or worker. If the module can't be found, the step will fail. The SecretManagement.Keeper module(s) can be installed from the PowerShell gallery.

Parameters

Keeper Secrets Manager Configuration (type: Sensitive) Variable name: #{Keeper.SecretsManager.RetrieveSecrets.Config} Keeper Secrets Manager configuration for KSM Application with permissions to retrieve secrets from the Keeper Vault. To generate KSM Configuration in Web Vault: Secrets Manager - KSM Application Name - Edit - Add Device, and switch to Method: Configuration file, preferably in Base64 format.

Vault Secrets to retrieve (type: Multi-line text box) Variable name: #{Keeper.SecretsManager.RetrieveSecrets.VaultSecrets} Use Secrets Manager Notation URIs to specify the Secrets to be returned from Keeper Vault, in the format SecretsManagerNotation URI | OutputVariableName where:

  • OutputVariableName is the optional Octopus output variable name to store the secret's value in. If this value isn't specified, an output name will be generated dynamically.

Multiple fields can be retrieved by entering each one on a new line. The line format is Notation | variable , where the variable name part is optional and if omitted auto generated variable names are used in the form of KsmSecret1, KsmSecret2, ...etc.

V8lFbio0Bs0LuvaSD5DDHA/field/login | MyLogin
V8lFbio0Bs0LuvaSD5DDHA/field/password | MyPass
V8lFbio0Bs0LuvaSD5DDHA/custom_field/phone[1][number] | MyOtherPhoneNum
V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png | MyImageBase64

Print output variable names (type: Checkbox) Variable name: #{Keeper.SecretsManager.RetrieveSecrets.PrintVariableNames} Write out the Octopus output variable names to the task log. Default: False

Oracle Key Vault Encryption

Protect Secrets Manager connection details with Oracle Key Vault

Keeper Secrets Manager integrates with Oracle Key Vault in order to provide protection for Keeper Secrets Manager configuration files. With this integration, you can protect connection details on your machine while taking advantage of Keeper's zero-knowledge encryption of all your secret credentials.

Features

  • Encrypt and Decrypt your Keeper Secrets Manager configuration files with Oracle Key Vault

  • Protect against unauthorized access to your Secrets Manager connections

  • Requires only minor changes to code for immediate protection. Works with all Keeper Secrets Manager SDK functionality

Prerequisites

  • Support the Java/Kotlin Secrets Manager SDK.

  • Required Oracle packages: oci-java-sdk-keymanagement, oci-java-sdk-common and oci-java-sdk-common-httpclient-jersey.

  • OCI Key needs ENCRYPT and DECRYPT permissions.

  • Supports the JavaScript Secrets Manager SDK

  • Requires the oci-keymanagement package from OCI SDK.

  • OCI KMS Key needs ENCRYPT and DECRYPT permissions.

  • Supports the Python Secrets Manager SDK

  • Requires oci package

  • User credentials to be used will need to have key vault permissions

  • Supports the .Net Secrets Manager SDK.

  • Requires OCI.DotNetSDK.Keymanagement.

  • Requires Encrypt and Decrypt permissions.

  • Supports the GoLang Secrets Manager SDK

  • Requires the oci-keymanagement package from OCI SDK.

  • OCI KMS Key needs ENCRYPT and DECRYPT permissions.

Setup

1. Install Module

Setting up project using Gradle or Maven

Gradle

repositories {
  mavenCentral()
}

dependencies {
  implementation("com.keepersecurity.secrets-manager:oracle:1.0.0")
  implementation("com.keepersecurity.secrets-manager:core:17.0.0")
  implementation("com.oracle.oci.sdk:oci-java-sdk-keymanagement:3.60.0")
  implementation("com.oracle.oci.sdk:oci-java-sdk-common-httpclient-jersey:3.60.0") // or the latest version
  implementation("com.oracle.oci.sdk:oci-java-sdk-common:3.60.0")
  implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
  implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
  implementation("com.google.code.gson:gson:2.12.1")
  implementation("org.slf4j:slf4j-simple:2.0.16")
  implementation("org.bouncycastle:bc-fips:1.0.2.4")
}

Maven

<!-- KMS-core -->
    <dependency>
     <groupId>com.keepersecurity.secrets-manager</groupId>
     <artifactId>oracle</artifactId>
     <version>1.0.0</version>
    </dependency>
    <dependency>
     <groupId>com.keepersecurity.secrets-manager</groupId>
     <artifactId>core</artifactId>
     <version>17.0.0</version>
    </dependency>

<!-- oci-kv -->
   <dependency>
       <groupId>com.oracle.oci.sdk</groupId>
       <artifactId>oci-java-sdk-keymanagement</artifactId>
       <version>3.60.0</version>
   </dependency>
   <dependency>
       <groupId>com.oracle.oci.sdk</groupId>
       <artifactId>oci-java-sdk-common-httpclient-jersey</artifactId>
       <version>3.60.0</version>
   </dependency>
   <dependency>
       <groupId>com.oracle.oci.sdk</groupId>
       <artifactId>oci-java-sdk-common</artifactId>
       <version>3.60.0</version>
   </dependency>
   	
   <!--gson -->
   <dependency>
   	<groupId>com.google.code.gson</groupId>
   	<artifactId>gson</artifactId>
   	<version>2.12.1</version>
   </dependency>

   <!--jackson-core -->
   <dependency>
   	<groupId>com.fasterxml.jackson.core</groupId>
   	<artifactId>jackson-core</artifactId>
   	<version>2.18.2</version>
   </dependency>
   	
   <!--jackson-databind -->
   <dependency>
   	<groupId>com.fasterxml.jackson.core</groupId>
   	<artifactId>jackson-core</artifactId>
   	<version>2.18.2</version>
   </dependency>
   	
   <!-- slf4j-api -->
   <dependency>
   	<groupId>org.slf4j</groupId>
   	<artifactId>slf4j-api</artifactId>
   	<version>1.7.32</version>
   	<scope>runtime</scope>
   </dependency>

   <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
       <version>2.0.16</version>
   </dependency>   	
   <!-- bc-fips -->
   <dependency>
   	<groupId>org.bouncycastle</groupId>
   	<artifactId>bc-fips</artifactId>
   	<version>1.0.2.4</version>
   </dependency>
   	

The Secrets Manager Oracle Key Vault module can be installed using npm

npm install @keeper-security/secrets-manager-oracle-kv

The Secrets Manager OCI KSM module can be installed using pip

pip3 install keeper-secrets-manager-storage-oracle-kms

oci is a prerequisite for the Oracle Key Vault integration. Install it to your machine using pip.

pip3 install oci

The Secrets Manager oracle KSM module can be installed using dotnet nuget package manager.

dotnet add package Keeper.SecretsManager.OracleKeyManagement

The Secrets Manager oracle KSM module Integration can be installed using

go get github.com/keeper-security/secrets-manager-go/integrations/oracle

2. Configure Oracle KV Connection

Ensure that you have an Oracle Key Vault instance available, and you know its OCID (Oracle Cloud Identifier). By default, the `oci key management` library will use the default OCI configuration file (~/.oci/config)

See the Oracle documentation for more information on setting up an Oracle Keys:

https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm

Alternatively, You will need to add the correct configuration for your OCI environment, including the details for accessing Oracle Key Vault.

The configuration file should look like this (replace with your actual details):

[DEFAULT] user=ocid1.user.oc1..example_unique_id fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx key_file=/path/to/your/private/api/key.pem tenancy=ocid1.tenancy.oc1..example_unique_id region=us-phoenix-1

3. Add Oracle Key Vault Storage to Your Code

Once Oracle connection has been configured, You can fetch the Key to encrypt / decrypt KSM configuration using integration and you need to tell the Secrets Manager SDK to utilize the KMS as storage.

Using Oracle Key Vault Integration

Once setup, the Secrets Manager Oracle Key Vault integration supports all Secrets Manager SDK functionality. Your code will need to be able to access the OCI Keys in order to manage the encryption and decryption of the KSM configuration file. Using Specified Connection credentials

To do this, create OracleKeyValueStorage instance and use this in SecretManagerOptions constructor.

The OracleKeyValueStorage will require the name of the Secrets Manager configuration file with profile and configuration.

import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretmanager.oracle.kv.OracleKeyValueStorage;
import com.keepersecurity.secretmanager.oracle.kv.OracleSessionConfig;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
import com.oracle.bmc.Region;


class Test {
	public static void main(String args[]){
		String configPath = "<~/.oci/config>";
		String cryptoEndpoint = "https://<>-crypto.kms.<oracle_cloud_region>.oraclecloud.com";
		String vaultId = "<OCI VAULT ID>";
		String keyId = "<OCI KEY ID>";
		String keyVersionId = "<OCI KEY VERSION>";
		String configFileLocation = "<KSM CONFIG FILE LOCATION>";
		String profile = "<OCI CONFIG PROFILE EX: DEFAULT>"; // name of your profile
		String oneTimeToken = "<Keeper One Time Token>";
		String managementEndpoint =  "https://<>-management.kms.<oracle_cloud_region>.oraclecloud.com";
		Region region = Region.<cloud_region>;
		Security.addProvider(new BouncyCastleFipsProvider());
		try{
			//set Oracle KV configuration, 
			OracleSessionConfig oracleSessionConfig = new OracleSessionConfig(configPath, cryptoEndpoint, managementEndpoint, vaultId, keyId, keyVersionId, region);
			//Get Storage 
			OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
			initializeStorage(oracleKeyValueStorage, oneTimeToken);
			SecretsManagerOptions options = new SecretsManagerOptions(oracleKeyValueStorage);
			//getSecrets(options)
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require an Oracle config file location, Oracle configuration profile(if there are multiple profile configurations) and the Oracle KMS Crypto endpoint , Oracle KMS Management endpoint as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS.

import { OCISessionConfig, OciKeyValueStorage } from "@keeper-security/secrets-manager-oracle-kv";
    const getKeeperRecordsOCI = async () => {
        const oracleConfigFileLocation = "/home/...../.oci/config";
        const oracleProfile = "DEFAULT";
        const kmsCryptoEndpoint = "https://<>-crypto.kms.<location>.oraclecloud.com";
        const kmsManagementEndpoint = "https://<>-management.kms.<location>.oraclecloud.com";
        const ociSessionConfig = await new OCISessionConfig(oracleConfigFileLocation, oracleProfile, kmsCryptoEndpoint,kmsManagementEndpoint);
        const logLevel = LoggerLogLevelOptions.info;
        let config_path = "<Keeper config File Path>";
        const oneTimeToken = "<one time token>";
        const keyId = 'ocid1.key.oc1.iad.<>.<>';
        const keyVersionId = "ocid1.keyversion.oc1.iad.<>.<>";
        const storage = await new OciKeyValueStorage(keyId, keyVersionId, config_path, ociSessionConfig,logLevel).init();
        await initializeStorage(storage, oneTimeToken);
        const { records } = await getSecrets({ storage: storage });
        console.log(records);
        const firstRecord = records[0];
        const firstRecordPassword = firstRecord.data.fields.find((x: { type: string; }) => x.type === 'bankAccount');
        console.log(firstRecordPassword.value[0]);
    };
    console.log("start");
    getKeeperRecordsOCI();

To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require a OCI Key ID, key version Id, KMS Crypto endpoint, KMS management endpoint, oracle config file location, configuration profile as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS and OCI session configuration shown below.

from keeper_secrets_manager_storage_oracle_kms import OracleKeyValueStorage, OCISessionConfig
from keeper_secrets_manager_core import SecretsManager
config_file_location = "/home/<user>/.oci/config"
profile = "DEFAULT"
kms_crypto_endpoint = "https://<kmsendpoint>.oraclecloud.com"
kms_mgmt_endpoint = "https://<kmsendpoint>.oraclecloud.com"
key_id = '<key_id>'
key_version_id = "<key_version_id>"
config_path = "<path to config json>"
one_time_token = "<Keeper One Time Token>"
oci_session_config = OCISessionConfig(config_file_location, profile, kms_crypto_endpoint, kms_management_endpoint)
storage = OracleKeyValueStorage(key_id=key_id, key_version=key_version_id, config_file_location=config_path, oci_session_config=oci_session_config,logger=None)
secrets_manager = SecretsManager(one_time_token,config=storage)
all_records = secrets_manager.get_secrets()
first_record = all_records[0]
print(first_record)

To do this, use OracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The storage will require a OCI Key ID, key version Id, KMS Crypto endpoint, KMS management endpoint, oracle config file location, configuration profile as well as the name of the Secrets Manager configuration file which will be encrypted by Oracle KMS and OCI session configuration shown below.

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OracleKeyManagement;
using SecretsManager;

public class Program
{
	private static async Task getOneIndividualSecret()
	{
	   Console.WriteLine("execution started");
            bool changeKey = false;
            bool decryptConfiguration = false;
            var OCIConfigFileLocation = "location";
            var profile = "DEFAULT";
            var kmsCryptoEndpoint = "crypto_endpoint";
            var kmsManagementEndpoint = "management_endpoint";
            var ociSessionConfig1 = new OciSessionConfig(OCIConfigFileLocation, profile, kmsCryptoEndpoint, kmsManagementEndpoint); 
            var path = "oci_ksm_conf_test.json";
            string keyId1 = "key1";
            string keyId2 = "key2";
            string keyVersionId1 = "key1version";
            string keyVersionId2 = "key2version";
            
            var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddConsole();
            });
            var logger = loggerFactory.CreateLogger<OracleKeyValueStorage>();
            var oracle_storage = new OracleKeyValueStorage(keyId2,keyVersionId2,path,ociSessionConfig1,logger );
            
            var dotnet_access_token = "<accesstoken>";
            SecretsManagerClient.InitializeStorage(oracle_storage, dotnet_access_token);
            if (changeKey)
            {
                oracle_storage.ChangeKeyAsync(keyId1,keyVersionId1,null).Wait();
            }
            if (decryptConfiguration)
            {
                var conf = await oracle_storage.DecryptConfigAsync(true);
                Console.WriteLine(conf);
            }
            var options = new SecretsManagerOptions(oracle_storage);
            var records_1 = await SecretsManagerClient.GetSecrets(options);
            records_1.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
	}

	static async Task Main()
	{
		await getOneIndividualSecret();
	}
}

To do this, use NewOracleKeyValueStorage as your Secrets Manager storage in the SecretsManager constructor.

The NewOracleKeyVaultStorage requires the following parameters to encrypt the KSM configuration using Oracle Vault:

ksmConfigFileName : The file name of KSM configuration.

keyConfig : Provide oracle key credentials KeyID and KeyVersionID.

oracleConfig : Provide oracle credentials VaultManagementEndpoint, VaultCryptoEndpoint.

By default, the oci-keymanagement library will use the default OCI configuration file (~/.oci/config).

package main

import (
	"encoding/json"
	"fmt"

	"github.com/keeper-security/secrets-manager-go/core"
	oraclekv "github.com/keeper-security/secrets-manager-go/integrations/oracle"
)

func main() {
	decryptConfig := true
	changeKey := true
	ksmConfigFile := ""
	oneTimeToken := "oneTimeToken"
	keyConfig := &oraclekv.KeyConfig{
		KeyID:        "ocid1.key.oc1.<>.<>.<>",
		KeyVersionID: "ocid1.keyversion.oc1.<>.<>.<>.<>",
	}
	oracleConfig := &oraclekv.OracleConfig{
		VaultManagementEndpoint: "https://<>-management.kms.<>.oraclecloud.com",
		VaultCryptoEndpoint:     "https://<>-crypto.kms.<>.oraclecloud.com",
		Profile:                 "",
		ProfileConfigPath:       "",
	}
	cfg := oraclekv.NewOracleKeyVaultStorage(ksmConfigFile, keyConfig, oracleConfig)
	secrets_manager := core.NewSecretsManager(
		&core.ClientOptions{
			Token:  oneTimeToken,
			Config: cfg,
		},
	)
	secrets, err := secrets_manager.GetSecrets([]string{})
	if err != nil {
		// do something
		fmt.Printf("Error: %s\n", err)
	} else {
		for _, secret := range secrets {
			fmt.Printf("Recieved secret: %s\n", secret.Title())
		}
	}

}

Additional Options

Change Key

We can change key that is used for encrypting the KSM configuration, examples below show the code needed to use it

//The method changeKey(keyID, keyVersion) will be used to encrypt the KSM config file with new Key and version. 

String newKeyID = "<new Key ID>";
String newKeyVersion = "<New Key Version>";
OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
oracleKeyValueStorage.changeKey(newKeyID, newKeyVersion); // Change the key for encryption/decryption
// To change the Oracle KMS key used for encryption, you can call the `changeKey` method on the `OciKeyValueStorage` instance.
const storage = await new OciKeyValueStorage(keyId, keyVersionId, configPath, ociSessionConfig).init();
await storage.changeKey(keyId2, keyVersionId2);
   storage = OracleKeyValueStorage(key_id=key_id, key_version=key_version_id, config_file_location=config_path, oci_session_config=oci_session_config,logger=None)
    
    new_key_id = "<new key id>"
    new_key_version_id = "<new key version>"
    isChanged = storage.change_key(new_key_id, new_key_version_id)
    print("Key is changed " + isChanged)
// To change the Oracle KMS key used for encryption, you can call the `ChangeKeyAsync` method on the `OracleKeyValueStorage` instance.
// using Microsoft.Extensions.Logging;

     var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddConsole();
            });
    var logger = loggerFactory.CreateLogger<OracleKeyValueStorage>();
    var oracle_storage = new OracleKeyValueStorage(keyId2,keyVersionId2,path,ociSessionConfig1,logger );
// If you want to change the key not oracle config, then pass nil in place of oracle config.
		updatedKeyConfig := &oraclekv.KeyConfig{
			KeyID:        "ocid1.key.oc1.<>.<>.<>",
			KeyVersionID: "ocid1.keyversion.oc1.<>.<>.<>.<>",
		}
	isChanged, err := cfg.ChangeKey(updatedKeyConfig, nil)

Decrypt Config

We can decrypt the config if current implementation is to be migrated onto a different cloud or if you want your raw credentials back. The function accepts a boolean which when set to true will save the decrypted configuration to file and if it is false, will just return decrypted configuration.

OracleKeyValueStorage oracleKeyValueStorage = new OracleKeyValueStorage(configFileLocation, profile, oracleSessionConfig);
oracleKeyValueStorage.decryptConfig(false); // Set false as a parameter to extract only plaintext.
//OR 
oracleKeyValueStorage.decryptConfig(true); // Set true as a parameter to extract plaintext and save config as a plaintext.
 const storage = await new OciKeyValueStorage(keyId, keyVersionId, config_path, ociSessionConfig).init();
 await storage.decryptConfig(true); // Saves to file
 const decryptedConfig = await storage.decryptConfig(true); // returns the decrypted config
 storage = OracleKeyValueStorage(key_id=key_id, key_version=key_version_id, config_file_location=config_path, oci_session_config=oci_session_config,logger=None)
 storage.decrypt_config(True)
//To decrypt the config file and save it again in plaintext, you can call the `DecryptConfigAsync` method on the `OracleKeyValueStorage` instance.
 var conf = await oracle_storage.DecryptConfigAsync(true);
 Console.WriteLine(conf);   
cfg := oraclekv.NewOracleKeyVaultStorage(ksmConfigFile, keyConfig, oracleConfig)
	secrets_manager := core.NewSecretsManager(
		&core.ClientOptions{
			Token:  oneTimeToken,
			Config: cfg,
		},
	)
// Pass true if you want to save decryptconfig in ksm config file, else pass false.
decryptedConfig, err := cfg.DecryptConfig(true) 

You're ready to use the KSM integration 👍

Check out the KSM SDKs documentation for more examples and functionality

PowerShell Plugin

Utilize PowerShell's Secret Management module to access secrets with the Keeper Secrets Manager PowerShell Plugin

Features

  • Retrieve secrets from the Keeper Vault to use in PowerShell

  • Integrate Keeper vault with PowerShell Secrets Manager

  • Update secret values in the Keeper Vault from PowerShell

  • Get files from the Keeper vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager PowerShell integration. In order to utilize this integration, you will need:

Secrets Manager requires PowerShell version 6 or greater. Microsoft distributes PowerShell version 6+ as a separate application from versions 5 and earlier.

See Microsoft's Documentation for installation details

  • PowerShell Version 6.0 or later

    • See Microsoft's Documentation for installation details

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A One Time Access Token

About

The Keeper Secrets Manager PowerShell plugin utilizes Microsoft PowerShell's Secret Management module to inject secrets from the Keeper Vault into your PowerShell scripts.

The Keeper Secrets Manager extension can be easily configured added as a secret vault into new or existing PowerShell Secret Management workflows.

For more information about PowerShell Secret Management, see the PowerShell docs on their GitHub page.

Installation

1. Install PowerShell Secret Management Module

Keeper Secrets Manager uses the Microsoft.PowerShell.SecretManagement module to manage secrets in PowerShell.

Install using PowerShell:

Install-Module -Name Microsoft.PowerShell.SecretManagement

See PowerShell Gallery for other installation options

2. Install Keeper Secrets Manager for PowerShell

Install the Keeper Secrets Manager PowerShell extension from the PowerShell Gallery.

Install-Module -Name SecretManagement.Keeper

See the PowerShell Gallery page for more installation options, or find the source code in GitHub.

To update SecretManagement, use the command: Update-Module -Name SecretManagement.Keeper

3. Install a PowerShell Secret Management Extension

If you already have a local secrets extension that you would like to use, you can skip this step

The Keeper Secrets Manager PowerShell plugin will need a secret management extension to store the plugin configuration locally to your machine.

Keeper recommends Microsoft.Powershell.SecretStore or SecretManagement.KeyChain

Install-Module -Name Microsoft.Powershell.SecretStore
Install-Module -Name SecretManagement.KeyChain

4. Register a Vault to use for Configuration Storage

If you already have a local secrets vault registered that you would like to use, you can skip this step

Register a secret vault for the previously installed secret management extension, so that the Keeper Secrets Manager plugin configuration can be stored.

Register-SecretVault -Name LocalStore -ModuleName Microsoft.Powershell.SecretStore
Register-SecretVault -Name LocalStore -ModuleName SecretManagement.KeyChain

The name of this vault will be used to register the Keeper extension. We used LocalStore in this example.

The Secret Management extension that you use for local storage may ask you to create a password for securely accessing the local vault.

Depending on your system settings, you may need to allow PowerShell to trust external modules. To do this, run the command:

set-executionpolicy remotesigned

5. Register the Keeper Vault

Register the Keeper Secrets Manager Vault using the local vault registered above to save your credentials, and a one time token to connect to Keeper.

Replace 'XXX' below with a one time token.

Register-KeeperVault -Name Keeper -LocalVaultName LocalStore -OneTimeToken XXX 

Alternatively you can use already generated config - replace 'XXX' below with a base64 encoded config.

Register-KeeperVault -Name Keeper -LocalVaultName LocalStore -Config XXX 

6. Set Keeper Vault as Default Secret Storage (Optional)

Set the Keeper vault you just added as the default secret storage. This will tell the PowerShell SecretsManagement module to use your Keeper vault when getting and setting secrets.

Set-SecretVaultDefault Keeper

This step is optional, but if you choose not to do it, you may receive secrets from your default vault if they have the same name, and you will need to add -Vault <keeper vault name> (e.g. -Vault keeper ) to Get-Secret, Set-Secret commands

The Keeper Secrets Manager PowerShell Plugin is now ready to be used

Source Code

Find the Keeper Secrets Manager PowerShell Plugin source code in the GitHub repository.

Usage

Find descriptions and examples of the most common usage of the Keeper Secrets Manager PowerShell plugin below.

For more information about PowerShell Secret Management commands, see the PowerShell docs on their GitHub page.

Starting with version 16.6.6 Get/Set commands allow use of \ as and escape character for dots in title. Use escape character only if there's dot in title, and escape both . and \ (ex. \., \\)

Listing Secrets

Run the following PowerShell command to see a list of secrets from Keeper

Get-SecretInfo -Vault <KEEPER VAULT NAME>
PS> Get-SecretInfo -Vault Keeper

Name                                  Type      VaultName
----                                  ----      ---------
bf3dg-99-Juh3feswgtFxg Home SSH       Hashtable Keeper
_3zT0HvBtRdYzKTMw1IySA ACME Login     Hashtable Keeper

Use the name set for your Keeper secrets vault, in the examples above we use Keeper.

The secrets shown are any records shared with the Secrets Manager Application. The Name column displays each record's UID and title.

Getting a Single Secret

Get information and values of a single secret

Get-Secret -Vault <KEEPER VAULT NAME> <RECORD NAME or UID> -AsPlainText
PS> Get-Secret -Vault Keeper "ACME Login" -AsPlainText

Name                           Value
----                           -----
login                          user2
password                       123
Files                          {file1.json, file2.zip}

Wrap the record name in quotation marks when there is a space in it.

-AsPlainText Shows the actual values of the secrets. Otherwise PowerShell shows them as a SecureString

Get a Value From a Secret

Utilize Keeper Dot Notation to identify a field to access. Note that you do not need the 'keeper://' prefix.

Get-Secret -Vault <KEEPER VAULT NAME> <RECORD NAME OR UID>.<FIELD> -AsPlainText
PS> Get-Secret -Vault Keeper "ACME Login.password" -AsPlainText
gmzN6E8@9E97%xPB6Pg0

Set a Value to a Secret

Update the value of a single secret field

Set-Secret -Vault <KEEPER VAULT NAME> <RECORD NAME OR UID>.<FIELD> <VALUE TO SET>

Keeper Vault is set as Default Vault

PS> Set-Secret -Vault Keeper "ACME Login.url" "acme.com"

Keeper Vault is not Default Vault

PS> Set-Secret -Vault Keeper "ACME Login.url" "acme.com" -Vault keeper

Download a File

Use dot notation to specify a file attached to a secret in the Keeper vault. Then pass that file to the Set-Content command to download it.

Get-Secret -Vault <KEEPER VAULT NAME> <RECORD NAME OR UID>.files[<FILENAME>] `
| Set-Content -Path <FILE PATH> -AsByteStream
PS> Get-Secret -Vault Keeper my_record.files[file1.json] `
| Set-Content -Path ./file1.json -AsByteStream

The specified file will be downloaded to the path location given to Set-Content

ServiceNow

Keeper credential storage integration with ServiceNow

About

The Management, Instrumentation, and Discovery (MID) Server integration with the Keeper Vault enables ServiceNow Orchestration, ServiceNow Discovery, and ServiceNow Service Mapping to dynamically retrieve credentials from the Keeper Vault without storing any credentials on the instance.

The instance maintains an unique identifier for every credential, along with its credential type (e.g., SSH, SNMP, or Windows) and any associated credential affinities. The MID Server obtains the credential identifier, credential type, and IP address from the instance, and then uses Keeper vault to resolve these elements into a usable credential.

Features

  • Use secrets from the Keeper vault as credentials for ServiceNow Orchestration, Discovery, and Service Mapping

  • Supports External Credential Storage for Discovery and Orchestration

  • Allows usage as a Custom Credential Provider

Use Cases

On-demand Discovery

  1. Trigger: An admin in ServiceNow initiates a discovery process for newly added infrastructure.

  2. Action: ServiceNow sends a request to the MID Server to start the discovery.

  3. MID Server: Retrieves the necessary credentials (SSH, SNMP, etc.) from Keeper Vault and performs the discovery.

  4. Result: The discovered assets are added to the ServiceNow Configuration Management Database (CMDB).

Incident Response

  1. Trigger: An incident is created in ServiceNow, requiring immediate action on a specific server.

  2. Action: ServiceNow triggers an orchestration workflow that involves the MID Server.

  3. MID Server: Fetches the required credentials from Keeper Vault to log into the affected server and execute predefined remediation steps.

  4. Result: The incident is resolved, and the actions taken are logged in ServiceNow.

Custom Credential Provider

  1. Trigger: A custom application integrated with ServiceNow requires specific credentials for operation.

  2. Action: The application queries ServiceNow for the required credentials.

  3. MID Server: Intercepts the request, fetches the credentials from Keeper Vault, and provides them to the custom application.

  4. Result: The custom application can proceed with its operation, using the credentials securely fetched from Keeper Vault.

Prerequisites

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper subscription

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • A ServiceNow instance with External Credential Storage plugin enabled

Setup

1. External Credential Storage (requires admin role)

  • The External Credential Storage plugin must be active.

  • The Enable External Credential Storage Discovery property is enabled.

System property:

A property called Enable External Credential Storage [com.snc.use_external_credentials] enables or disables the External Credential Storage plugin after it is activated. This property is located in Discovery Definition > Properties and Orchestration > MID Server Properties, and is enabled when you activate the plugin.

If you disable external credential storage with the system property, the system automatically sets all the external credentials to inactive in the instance. If you re-enable the feature with this property, the system does not reset the external credential records to active. You must reactivate each credential record manually.

2. Installing Keeper Credential Resolver

  • Download the latest version of Keeper Credential Resolver JAR file from here.

  • In ServiceNow, navigate to "MID server - JAR files" -> New

    • Manage Attachments -> upload Keeper Credential Resolver JAR

    • Fill in name, version etc. as desired

    • Click Submit

  • Navigate to "MID server - Properties" -> New

    • Set Name: ext.cred.keeper.ksm_config, Value: base64 version of the configuration generated for the corresponding KSM Application.

    • Optional: Set the property ext.cred.keeper.ksm_label_prefix to the desired prefix (by default resolver uses mid_ as a label prefix)

    • Optional: Set the property ext.cred.keeper.use_ksm_cache to "true" to enable caching (use when you expect at least a few thousand requests per 10 seconds)

    • Alternatively, you can edit config.xml directly (by default in /opt/servicenow/mid/agent/) by adding the keys and restarting the server (setting the label prefix is optional - the default prefix is shown below)

<parameter name="ext.cred.keeper.ksm_config" secure="true" value="[KSM_CONFIG_BASE64_STRING]"/>
<!-- optional -->
<parameter name="ext.cred.keeper.ksm_label_prefix" value="mid_"/>
<!-- optional -->
<parameter name="ext.cred.keeper.use_ksm_cache" value="true"/>

Use secure="true" option for all sensitive parameters and remember to restart the server to encrypt the values.

3. Configuring discovery credentials

To consume Keeper vault credentials from your MID server, you will need to:

  • Create a secret in Keeper vault and share it to the corresponding KSM Application

  • Configure the resolver to use that secret

Creating a secret in Keeper vault and mapping fields

Keeper record types are dynamic and easy to customize, and there are no specific record types matching corresponding credential types in ServiceNow.

Keeper External Credential Resolver uses custom field labels to match record data with MID Server's table columns (discovery_credential table). Just label all required custom fields to match the table columns for a given credential type and prefix that label with "mid_" (see below how to configure custom prefix)

Credential types that require username/password should use records of type Login, and add any custom fields required by the credential type - ex. type=hidden, label="mid_pkey"

Any other types that may not have username/password is best to use File/Photo records which don't have any standard fields and that makes it easier to navigate the custom fields.

To change the custom field labels prefix update the config.xml in MID Server with the parameters below and restart the MID Server.

<parameter name="ext.cred.keeper.ksm_label_prefix" value="mid_"/>
  • You may use custom fields with type text, multiline or hidden depending on the visibility you want in your Keeper Vault.

  • When Login record type is used, any custom fields for username/password are ignored (even if properly labeled mid_user, mid_pswd) as these values always come from the Login record type standard fields - Login/Password.

  • When used with "External credential store" option the map keys returned from resolve method must conform to IExternalCredential interface from snc-automation-api.jar (values start with VAL_ prefix).

    • Supported key values in current version (Utah): user, pswd, passphrase, pkey, authprotocol, authkey, privprotocol, privkey, secret_key, client_id, tenant_id, email - corresponding field labels should be prefixed with mid_ in Keeper records to be extracted and mapped properly.

  • When used as Custom External Credential Resolver, any custom field could be mapped if properly prefixed in Keeper vault and present in corresponding credential type. The credential map returned from the resolve method is expected to have keys matching with the column names in discovery_credential table ex. sn_cfg_ansible, sn_disco_certmgmt_certificate_ca, cfg_chef_credentials, etc.

Examples:

  • Credential type jdbc - map to Keeper record type Login (using standard Login/Password fields, no additional setup required)

  • Credential type api_key - map to Keeper record type Login and manually add custom fields of type hidden with labels mid_ssh_private_key, and mid_ssh_passphrase (optional)

  • Credential type gcp - map to Keeper record type File Attachment/Photo and manually add the required custom fields mid_email - text, mid_secret_key - hidden.

Finding credentials in the Keeper Vault

The Credential ID passed from MID Server to the Credential Resolver must be either a valid record UID (22 alphanumeric characters incl. "-" and "_") or in the following format type:title

The type:title format allows searching by record type or by title (or both, but single ":" is an invalid combination)

When using the type:title format for the credential, please make sure there's only one matching record, since multiple matches will result in an error.

Using record UID for matching is recommended to guarantee a single record match, and to avoid downloading all records with every single request to do local searches by type:title (due to the zero knowledge nature of the Keeper vault - searches must be local).

Examples

Note: Zero or two or more matches result in an error

  • Find by Record UID - Credential ID: ABCDABCDABCDABCDABCDAB

  • Find by type and title - Credential ID: login:MyLogin

  • Find by title - Credential ID: :MyLogin

  • Find by type - Credential ID: login:

Configuring the resolver to use a secret

In the ServiceNow UI:

  • Navigate to "Discovery - Credentials" -> New

    • Select a credential type from the list

    • Tick the "External credential store" check box. The Username and Password fields disappear, and the Credential ID field and Credential storage vault menu appear.

    • Fill in a meaningful name

    • Set "Credential ID" to the record UID of your secret or provide a search string in the form type:title or just :title and make sure it resolves to a single record

    • From the Credential storage vault menu, you can select either None, the Keeper vault, or a custom external credential storage vault.

      1. To use a custom external credential storage vault, navigate to Vault Configurations [vault_configuration.list] in the instance.

      2. Create a new record using a name associated with an imported JAR file for a custom credential resolver.

    • Optional: Click "Test credential" and select a MID server and a target to test against to test everything is working

Caching Requests and Throttles

If too many requests are sent to Keeper within a certain time period, we will respond with a throttle error response. The plugin will try to resolve "throttled" errors by default by adding a random delays and retrying later, which works well for up to 1000-3000 requests per 10 sec interval (throttles start after 300-600 requests/10 sec).

If you expect 5000+ requests in less than 10 seconds we recommend to enable caching by setting ext.cred.keeper.use_ksm_cache parameter to "true" in config.xml and restarting the MID Server. Cached data is stored in an encrypted file ksm_cache.dat in MID Server's work folder. Cache is updated at most once every 5 minutes or with the next request.

Troubleshooting

Check the logs

Check the log files inside logs/ in the agent installation folder for logs and errors. The resolver logs a line for each credential ID that it successfully queries, and also logs the fields that the credentials were extracted from.

If a particular credential ID is failing, search for that ID in the logs, and check that it is successfully queried and that the credentials were extracted from the fields you expected.

You will also find any exceptions that the resolver throws in the logs, including errors locating a record or finding fields, or if it couldn't communicate with Keeper vault.

Use the Test Credential feature

When creating or configuring a credential in the ServiceNow UI, you should be able to click "Test credential" to perform a quick targeted test. Select the MID server that should query the Keeper vault, and select a target that the credential should work for to check that everything works as expected. If it doesn't, check the logs for errors and debug information as detailed above.

TeamCity

Keeper Secrets Manager plugin for accessing secrets in TeamCity builds

About

TeamCity is a general-purpose CI/CD software platform that allows for flexible workflows, collaboration and development practices. A solution that will allow for successful continuous integration, continuous delivery, and continuous deployment within your DevOps process.

The plugin allows TeamCity servers (version 2018.1 or newer) to integrate with Keeper Secrets Manager to make managing secrets in TeamCity easier and more secure.

Features

  • Use secrets from the Keeper vault in TeamCity builds

  • Keeper Secrets Manager plugin installs as a TeamCity Connection

Prerequisites

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager add-on enabled for your Keeper subscription

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The TeamCity plugin accepts Base 64 format configurations

Installation

Installing Plugin from JetBrains Plugins Repository

  • Go to Administration | Plugins in TeamCity and click Browse plugins repository.

  • Find the Keeper Secrets Manager plugin, click Get, and then Install to http[s]://<teamcityUrl>.

  • Confirm the plugin installation by clicking Install.

  • To enable the plugin after installation, click the plugin context menu and select Load.

Installing Plugin via Web UI

  • Download the latest version of TeamCity KSM plugin ZIP file from here.

  • Go to the Administration | Plugins page and upload the plugin ZIP archive from your local machine using the corresponding link.

Installing Plugin Manually

  • Copy the ZIP plugin package into the<TeamCity Data Directory>/plugins directory. If you have an earlier version of the plugin in the directory (though the plugin package can be named differently), remove it.

Enabling Plugin

  • To enable the plugin after installation, click the plugin context menu and select Load. The plugin will be enabled without the server restart.

Uninstalling Plugin via Web UI

  • Go to Administration | Plugins, locate an external plugin in the list, click the arrow icon next to it, and select Delete.

  • Once the plugin is deleted, the option to restart the server appears on the page. Click it and check that the plugin version is no longer listed in Administration | Plugins.

Uninstalling Plugin Manually

  • Remove the plugin package from the <TeamCity Data Directory>/plugins directory and restart the TeamCity server.

Setup

Configuring Connections

When created, a connection can be used in all the nested subprojects of the current project. If you add a connection in the Root project, it will become available on the whole server.

To add a connection, go the target project's settings, open the Connections page, and click Add Connection. Select the connection type Keeper Vault, set its Display name to distinguish it from the others, and configure it as described below.

Adding connection of type Keeper Vault
  • In Project Administration | Connections, click Add Connection.

  • Select Keeper Vault as the connection type.

  • Specify the token - paste a valid KSM config (see Prerequisites).

  • Save the connection.

Configure Keeper Vault Connection

Using secrets in TeamCity builds

To consume Keeper vault secrets from your TeamCity server, you will need to:

  • Create a secret in Keeper vault and share it to the corresponding KSM Application

  • Configure a TeamCity parameter that resolves the secret using Secrets Manager Notation URIs

Using Build Parameters in Build Configuration Settings

In most build configuration settings, you can use a reference to a build parameter instead of using the actual plain-text value. Before starting a build, TeamCity resolves all references with the available parameters. If there are references that cannot be resolved, they are left as is, and a respective warning appears in the build log. To reference a build parameter, use its name enclosed in percentage characters: for example, %env.KsmSecret1%.

Parameters tab allows adding, editing, and deleting new parameters/properties/variables, or redefining their predefined values.

Any text enclosed in percentage characters will be interpreted by TeamCity as a reference to a parameter. If the parameter cannot be found in the build configuration, this reference becomes an implicit agent requirement and such build configuration can only be run on an agent with this parameter defined. The agent-defined value will be used in the build. If you want to prevent TeamCity from treating the text in the percentage characters as a reference to a parameter, use two percentage characters. Every occurrence of %% in the values where parameter references are supported will be replaced with % before passing the value to the build. For example, if you want to pass %Y%m%d%H%M%S into the build, change it to %%Y%%m%%d%%H%%M%%S.

Example Workflow

Define a build parameter on a build configuration level and use it in a build step.

  1. Go to Build Configuration Settings | Parameters.

  2. Click Add new parameter.

  3. Enter the parameter's name and value. Change parameter's Kind to Environment variable (env.).

    • Name: username

    • Value: %keeper://UserRecord1/fields/login%

    • Adding New Parameter
  4. Save the parameter.

  5. Go to Build Steps.

  6. Click Add build step.

  7. Choose the Command Line runner type.

  8. In the Custom script field, enter the following command: echo UserName %env.username%

    For a build, this command will be resolved as follows (note that actual value is masked in logs but used in actual commands):

    echo UserName *****
  9. Save the build step and run a new build.

The plugin accepts both Keeper Notation prefix keeper://NotationURI and TeamCity style prefix keeper:NotationURI in build parameters, environment variables etc. Check the examples below.

Parameter Examples:

  • Environment variable env.User - keeper:abcdABCDabcdABCDuvwxyz/field/login

  • Environment variable env.Secret - keeper://MyRecord1/custom_field/Secret1

Teller

Keeper Secrets Manager integration with Teller for dynamic secrets retrieval

Features

  • Retrieve secrets from the Keeper Vault within Teller environments

  • Set secret credentials as environment variables in Teller

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Teller integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Teller integration accepts Base64 format configurations

Setup

Getting a Secrets Manager configuration

Using Keeper Commander, add a new client to an application and initialize the configuration to a Base64 string. This will be the long text hash that appears after the "Initialized Config:" label.

My Vault> sm client add --app MyApp --config-init b64

Successfully generated Client Device
====================================

Initialized Config: eyJob3N0bmFtZSI6ICJr....OUk1ZTV1V2toRucXRsaWxqUT0ifQ==
IP Lock: Enabled
Token Expires On: 2021-10-19 15:31:31
App Access Expires on: Never

That value needs to be assigned to an environment variable with the name KSM_CONFIG.

Creating a Teller configuration

teller will pull variables from your Keeper Vault, and will populate your current working session so you can work safely and much more productively.

teller needs a tellerfile. This is a .teller.yml file that lives in your repo, or one that you point teller to with teller -c your-conf.yml. Run teller new and follow the wizard, pick the providers you like and it will generate a .teller.yml for you.

Alternatively, you can use the following minimal template:

project: project_name
opts:
  stage: development

providers:
  # requires a configuration in: KSM_CONFIG=base64_config
  # or file path KSM_CONFIG_FILE=ksm_config.json
  keeper_secretsmanager:
    # pull multiple key-value pairs from a single record
    # all non-empty fields are mapped by their labels,
    # if empty then by field type, and numeric suffix 1,2,...,N on duplicates
    env_sync:
      path: [recordUID]

    # use Keeper Notation to select individual field values
    # https://docs.keeper.io/secrets-manager/secrets-manage
    env:
      USER:
        path: [recordUID]/field/login
      PSWD:
        path: [recordUID]/field/password

Running from command line

With a .teller.yml file in the current directory, or one that you point teller to with teller -c your-conf.ymlnow you can just run processes with:.

$ teller run node src/server.js
Service is up.
Loaded configuration: Mailgun, SMTP
Port: 5050

Using a GitHub Action

Add a teller step.

# set up teller step
- name: Setup Teller
  uses: spectralops/setup-teller@v2
- name: Run a Teller task (show, scan, run, etc.)
  run: teller run [args]

Full example below is using the default config file .teller.yml which can be replaced in the run command with a custom file that you point teller to with teller -c your-conf.yml.

name: run with teller
on:
  push:
    branches:
      - master
      - main
  pull_request:

jobs:
  build:
    name: Build your code
    runs-on: ubuntu-latest

    steps:
      - name: Clone repo
        uses: actions/checkout@master


      # set up teller
      - name: Setup Teller
        uses: spectralops/setup-teller@v2

      - name: Run a Teller task (show, scan, run, etc.)
        run: teller run npm run build

Terraform Plugin

Keeper Secrets Manager Terraform plugin for accessing secrets in Terraform builds

Features

  • Retrieve secrets from the Keeper Vault to use in Terraform builds

  • Inject credentials directly into Terraform build scripts

  • Get Files from the Keeper Vault

For a complete list of Keeper Secrets Manager features see the Overview

Prerequisites

This page documents the Secrets Manager Terraform integration. In order to utilize this integration, you will need:

  • Keeper Secrets Manager access (See the Quick Start Guide for more details)

    • Secrets Manager addon enabled for your Keeper account

    • Membership in a Role with the Secrets Manager enforcement policy enabled

  • A Keeper Secrets Manager Application with secrets shared to it

    • See the Quick Start Guide for instructions on creating an Application

  • An initialized Keeper Secrets Manager Configuration

    • The Terraform integration accepts JSON and Base 64 format configurations

About

The Keeper Terraform Plugin utilizes Keeper Secrets Manager to provide access to secret credentials saved in the Keeper Vault. The Keeper Terraform plugin allows for injecting secrets directly into Terraform builds securely using Keeper's zero-knowledge infrastructure.

Installation

Registry install

The Keeper Secrets Manager provider page is located here

To install this provider, add the following code to your Terraform configuration and run terraform init:

terraform {
  required_providers {
    secretsmanager = {
      source = "keeper-security/secretsmanager"
      version = ">= 1.0.0"
    }
  }
}

provider "secretsmanager" {
  # Configuration options
}

Manual Installation

Download the latest version of the Terraform Provider for your platform from our GitHub release page and copy the archive to the corresponding Terraform plugin folder (creating any missing folders in the path). Initialize source with full provider URL: source = "github.com/keeper-security/secretsmanager"

SETLOCAL EnableExtensions && ^
mkdir %APPDATA%\.terraform.d\plugins\github.com\keeper-security\secretsmanager && ^
cd %APPDATA%\.terraform.d\plugins\github.com\keeper-security\secretsmanager && ^
curl -SfLOJ https://github.com/keeper-security/terraform-provider-secretsmanager/releases/download/v1.0.0/terraform-provider-secretsmanager_1.0.0_windows_amd64.zip
mkdir -p ~/.terraform.d/plugins/github.com/keeper-security/secretsmanager && \
cd ~/.terraform.d/plugins/github.com/keeper-security/secretsmanager && \
curl -SfLOJ https://github.com/keeper-security/terraform-provider-secretsmanager/releases/download/v1.0.0/terraform-provider-secretsmanager_1.0.0_darwin_amd64.zip
mkdir -p ~/.terraform.d/plugins/github.com/keeper-security/secretsmanager && \
cd ~/.terraform.d/plugins/github.com/keeper-security/secretsmanager && \
curl -SfLOJ https://github.com/keeper-security/terraform-provider-secretsmanager/releases/download/v1.0.0/terraform-provider-secretsmanager_1.0.0_linux_amd64.zip

For help on manually installing Terraform Providers, please refer to the official Terraform documentation.

Usage

Configure the Provider

The Keeper Secrets Manager provider is used to interact with the resources supported by Keeper Secrets Manager. The provider needs to be configured with Keeper credentials before it can be used.

terraform {
  required_providers {
    secretsmanager = {
      source  = "keeper-security/secretsmanager"
      version = ">= 1.0.0"
    }
 }
}

provider "secretsmanager" {
  # Specify config contents as a string or load from file
  # credential = "<CONFIG FILE CONTENTS BASE64>"
  credential = file("/path/to/config.json")
}

Configuration File Contents

  • app_key - (Required) Application key.

  • client_id - (Required) Client ID.

  • private_key - (Required) Private key.

  • hostname - (Optional) By default plugin will connect to keepersecurity.com

For more information on creating a Secrets Manager configuration, see the Configuration Documentation

Get Secrets Using Data Sources

A data source is provided for each standard Keeper record type, which facilitates easy fetching of secret credentials.

Data sources are accessed using the following format:

data "<data_source_name>" "<record_type_reference>" {
    path = "<record_uid>"
}

For example, using a Login type record:

data "secretsmanager_login" "my_login_record" {
    path = "<RECORD_UID>"
}

To access any additional custom fields or standard fields for user defined record types use secretsmanager_field data source

List of supported record types

Record Type
Data Source Name

Address

"secretsmanager_address"

Bank Account

"secretsmanager_bank_account"

Bank Card

"secretsmanager_bank_card"

Birth Certificate

"secretsmanager_birth_certificate"

Contact

"secretsmanager_contact"

Database Credentials

"secretsmanager_database_credentials"

Drivers License

"secretsmanager_drivers_license"

Encrypted Notes

"secretsmanager_encrypted_notes"

Field

"secretsmanager_field"

File

"secretsmanager_file"

Health Insurance

"secretsmanager_health_insurance"

Login

"secretsmanager_login"

Membership

"secretsmanager_membership"

Passport

"secretsmanager_passport"

Photo

"secretsmanager_photo"

Record

"secretsmanager_record"

Server Credentials

"secretsmanager_server_credentials"

Software License

"secretsmanager_software_license"

SSH Keys

"secretsmanager_ssh_keys"

SSN Card

"secretsmanager_ssn_card"

To see the fields available to each data source see Record Types Data Source Reference

For more information on record types see record types documentation

Accessing Record Fields

To access a secret credential saved to a field in a record, access the field as part of the data source.

Access the field of a typed record data source

Use this format to access fields of a typed data resource

${ data.<data_source_name>.<record_type_reference>.<field> }

Example: access the password of a login type data source

${ data.secretsmanager_login.my_login_secret.password }

Use the field data source to query any field in a record with Keeper Notation

Create a data source using the "secretsmanager_field" data source type, and specify a field query in the path property.

data "secretsmanager_field" "my_field" {
  path = "<record UID>/field/login"
}

The field query uses the format: "<UID>/field/<field type>"

Creating Records With Resources

Keeper provides Terraform resources for the major Keeper record types shown above. Using these resources, Keeper records can be created using the Keeper Secrets Manager Terraform plugin.

To create a record, use the resource corresponding to the record type that you would like to use.

Each record resource requires at least a folder_uid and title as well as values for each record field.

Example login resource

resource "secretsmanager_login" "login" {
    folder_uid: "4PbDLf8UF4od87wJt-fdyQ"
    tile: "My Login Record"
    [...]
}

Folder UID

To create records, Keeper Secrets Manager requires a folder UID so that it knows where to create the new records.

A folder UID can be found in the Keeper Vault or by using Keeper Commander.

The given folder must by accessible by the Keeper Secrets Manager Application being used by your Terraform plugin. The folder must also have at least one record in it before being used by Keeper Secrets Manager.

Title

The record title.

Record Fields

The value and settings for each record field can be set in the resource. For information on the available fields per record type, see the resource definitions.

Each field is represented as an object in the resource.

Example login field

resource "secretsmanager_login" "login" {
    [...]
    login {
        value = "MyUsername"
        label = "Username"
	required = true
    }
}

Setting Field Values

Use the value field to set the intended value for each field. The format of fields can differ, for example the login field type takes a string, while the name field takes an object with "first", "middle" and "last" fields.

For reference of each field's value format see the resource documentation.

Setting Field Settings

Each field can be configured with various settings:

Field
Accepted Value
Description

label

string

The field label

required

boolean

if True, the field will be considered required by the Keeper Vault

privacy_screen

boolean

if True, the field will be hidden in the Keeper Vault

Password Field

The password field has some special features.

Password Generation

Records created using the Terraform plugin can have a password generated automatically. To have the plugin generate a password, do not provide a value field to the password, and instead use generate = "True"

The password generation can be configured to generate a password of a specified length using the complexity field

complexity {
    length: 16
}

Additionally, password fields have an extra configuration setting: enforce_generation which when true will make the Keeper Vault enforce that the password can only be generated and not set by a user.

To have Terraform regenerate a password, it needs to notice a difference in the generate field. To allow for triggering a difference, the generate field accepts both "true" and "yes" values. Change from one to the other to trigger a regeneration.

Examples

Read Credentials

This example provisions Keeper Secrets Manager, reads a login type data source, and accesses each field of the data source.

terraform {
  required_providers {
    secretsmanager = {
      source  = "keeper-security/secretsmanager"
      version = ">= 1.0.0"
    }
    local = {
      source = "hashicorp/local"
      version = "2.1.0"
    }
  }
}

provider "local" { }
provider "secretsmanager" {
  # Specify config contents as a string or load from file
  # credential = "<CONFIG FILE CONTENTS BASE64>"
  credential = file("~/.keeper/ksm-config.json")
}

data "secretsmanager_login" "db_server" {
  path        = "<record UID>"
}

resource "local_file" "out" {
    filename        = "${path.module}/out.txt"
    file_permission = "0644"
    content         = <<EOT
UID:    ${ data.secretsmanager_login.db_server.path }
Type:   ${ data.secretsmanager_login.db_server.type }
Title:  ${ data.secretsmanager_login.db_server.title }
Notes:  ${ data.secretsmanager_login.db_server.notes }
======
Login:    ${ data.secretsmanager_login.db_server.login }
Password: ${ data.secretsmanager_login.db_server.password }
URL:      ${ data.secretsmanager_login.db_server.url }
TOTP:
-----
%{ for t in data.secretsmanager_login.db_server.totp ~}
URL:    ${ t.url }
Token:  ${ t.token }
TTL:    ${ t.ttl }
%{ endfor ~}
FileRefs:
---------
%{ for fr in data.secretsmanager_login.db_server.file_ref ~}
UID:      ${ fr.uid }
Title:    ${ fr.title }
Name:     ${ fr.name }
Type:     ${ fr.type }
Size:     ${ fr.size }
Last Modified:  ${ fr.last_modified }
Content/Base64: ${ fr.content_base64 }
%{ endfor ~}
EOT
}

output "db_secret_login" {
  value = data.secretsmanager_login.db_server.login
}

Create a Keeper Record

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    secretsmanager = {
      source  = "keeper-security/secretsmanager"
      version = ">= 1.1.0"
    }
    local = {
      source = "hashicorp/local"
      version = "2.1.0"
    }
  }
}

provider "local" { }
provider "secretsmanager" {
  # Specify config contents as a string or load from file
  # credential = "<CONFIG FILE CONTENTS BASE64>"
  credential = file("~/.keeper/ksm-config.json")
}

resource "secretsmanager_membership" "membership" {
	folder_uid = "<FOLDER UID>"
	title = "test_membership_resource"
	notes = "test_membership_resource"
	account_number {
		label = "MyAccountNumber"
		required = true
		privacy_screen = true
		value = "AccountNumber#1234"
	}
	name {
		label = "Jane"
		required = true
		privacy_screen = true
		value {
			first = "Jane"
			middle = "D"
			last = "Doe"
		}
	}
	password {
		label = "MyPass"
		required = true
		privacy_screen = true
		enforce_generation = true
		generate = "true"
		complexity {
			length = 16
		}
		#value = "to_be_generated"
	}
}

resource "local_file" "out" {
    filename        = "${path.module}/out.txt"
    file_permission = "0644"
    content         = <<EOT
FUID:   ${ secretsmanager_membership.membership.folder_uid }
UID:    ${ secretsmanager_membership.membership.uid }
Type:   ${ secretsmanager_membership.membership.type }
Title:  ${ secretsmanager_membership.membership.title }
Notes:  ${ secretsmanager_membership.membership.notes }
======

Account Number:
---------------
%{ for n in secretsmanager_membership.membership.account_number ~}
Type:   ${ n.type }
Label:   ${ n.label }
Required:   ${ n.required }
Privacy Screen:   ${ n.privacy_screen }
Value:   ${ n.value }
%{ endfor }

Name:
-----
%{ for n in secretsmanager_membership.membership.name ~}
Type:	${ n.type }
Label:	${ n.label }
Required:	${ n.required }
Privacy Screen:   ${ n.privacy_screen }
First Name:		${ n.value.0.first }
Middle Name:	${ n.value.0.middle }
Last Name:		${ n.value.0.last }
%{ endfor }

Password:
---------
%{ for n in secretsmanager_membership.membership.password ~}
Type:   ${ n.type }
Label:	${ n.label }
Required:   ${ n.required }
Privacy Screen:		${ n.privacy_screen }
Enforce Generation:	${ n.enforce_generation }
Generate:	%{ if n.generate != null }${n.generate}%{ endif }
Complexity:	Length = ${ n.complexity.0.length }
Value:   ${ n.value }
%{ endfor }

EOT
}

output "record_uid" {
  value = secretsmanager_membership.membership.uid
}
output "record_title" {
  value = secretsmanager_membership.membership.title
}

For more examples, check out the examples folder in the source code.

Windows Credential Manager

Store and Retrieve Secrets from the Windows Credential Manager

Overview

Windows Credential Manager is a native Windows utility that stores sensitive information, such as passwords and secrets, and allows applications to securely access it.

Keeper provides a utility, the Windows Credential Utility, that interacts with native windows APIs to store and retrieve secrets from the Windows Credential Manager. It can be used by any integration, plugin, or code base to store and retrieve credentials, secrets, and passwords in the Windows Credential Manager simply and natively.

The code base for the Windows Credential Utility can be found here:

LogoGitHub - Keeper-Security/windows-credential-utility: A utility for natively interacting with Windows Credential ManagerGitHub

The binary needed to use the above utility can be found here:

LogoReleases · Keeper-Security/windows-credential-utilityGitHub

To use the Windows Credential Utility, you can either

  • deploy the pre-built binary from the releases page

  • or import it into your code base.

Both use cases are covered below.

Usage - Executable

Downloading the Executable

Download the latest version executable from the releases page and optionally add it to PATH to get started.

Using the Executable

The executable supports two commands:

  1. set

  2. get

Both commands require an application name (i.e. the name of the credential in / to be stored in the Windows Credential Manager) as the first argument.

set

set requires a second argument of the secret to be stored. This can be either a:

  1. BASE64 string

  2. JSON string

  3. Path to an existing JSON file

When the secret is saved to Windows Credential Manager it is first encoded into a BASE64 format (if not already a BASE64 string). This standardizes the format for both consistent storage and to make it easier to consume by Keeper integrations and products.

get

get returns the stored BASE64 encoded config to stdout and exits with a 0 exit code. The requesting integration can capture the output for consumption. Any errors encountered retrieving the config will return an non-zero exit code and write to stderr.

Example

# Save a secret
wcu set APPNAME eyJ1c2VybmFtZSI6ICJnb2xsdW0iLCAicGFzc3dvcmQiOiAiTXlQcmVjaW91cyJ9
# or
wcu set APPNAME config.json

# Retrieve a secret
wcu get APPNAME

XSOAR

Use Secrets Manager with automated workflows in Cortex XSOAR

About

Use credentials from your Keeper Vault in XSOAR workflows. Integrate with Keeper Secrets Manager to securely access all the platforms and services you connect to with XSOAR.

Setup

Activate Keeper Secrets Manager

Follow the Quick Start Guide to enable Keeper Secrets Manager on your account.

Create A Keeper Secrets Manager Configuration

Follow the steps in the documentation page to create a Secrets Manager configuration.

Configure Keeper Secrets Manager on Cortex XSOAR

In XSOAR, follow these steps to configure the Keeper Secrets Manager integration.

  1. Navigate to Settings > Integrations > Servers & Services.

  2. Search for "Keeper Secrets Manager"

  3. Click Add instance to create and configure a new integration instance.

Configure the instance to use the Keeper Secrets Manager integration

The following options are available to configure your XSOAR integration:

Parameter
Description

KSM Configuration (Required)

The KSM config to use for connection. Paste in the configuration generated by the steps above.

Trust any certificate

When 'trust any certificate' is selected, the integration ignores TLS/SSL certificate validation errors. Use to test connection issues or connect to a server without a valid certificate.

Fetches credentials

If selected, credentials are fetched from login records.

Concat username to credential object name

when selected, the username and credential name will be combined. Use to make the credential object unique in case of duplicate names in different folders/secrets.

A comma-separated list of credential names to fetch.

Partial names are not supported. If left empty, all credentials will be fetched.

Once configured, click Test to validate the URLs, token, and connection.

Available KSM Commands

The following commands can be used in XSOAR. Use these commands to fetch records and files from the Keeper Vault. Only records that are shared to the Secrets Manager Application can be accessed by these commands.

List Available Credentials

!ksm-list-credentials

This command will only show records which can be used as credentials in XSOAR. Records must have a login and password to be used as a credential.

List Available Records

!ksm-list-records

This command shows all records available to XSOAR through the KSM Application.

Get a Keeper Record by Title

!ksm-find-records title="<RECORD TITLE>"

add partial_match=True to use partial matching of the record title

Get a Value From a Keeper Record

!ksm-get-field notation="keeper://<UID>/field/login"

See the Keeper Notation documentation for more details on using keeper notation to identify fields

List Files Attached to Keeper Records

!ksm-list-files

Get a File from a Keeper Record

!ksm-get-file file_uid="<UID>"
!ksm-get-infofile file_uid="<UID>"

Find Records That Have Files Attached With Given Filename

!ksm-find-files file_name="<FILENAME>"

Using Commands in a Playbook

To use Keeper Secrets Manager commands in your XSOAR playbooks, click "Task Library" and search for "Keeper" to show all the available commands.

List Available Keeper Commander

Select a command to use and fill in the required fields if any.

Example: Get a Password From a Keeper Record

Fetch a password from the Keeper Vault to login to other services in your playbook.

  1. Search for the "ksm-get-field" command and click to add it to your playbook

  2. Enter Keeper notation pointing to the password using the UID of the record you want to use. This will look like: <UID>/fields/password

    Any field in a record can be fetched this way. See Keeper Notation documentation for more information

  3. Click "OK" to add the task to your playbook

You can add additional tasks after the ksm-get-field task to use the password.