Nathan Coad a7d839e712
All checks were successful
continuous-integration/drone/push Build is passing
test2
2024-01-09 16:44:36 +11:00
2024-01-09 15:44:30 +11:00
2024-01-09 11:49:59 +11:00
2024-01-09 16:44:36 +11:00
2024-01-08 15:16:41 +11:00
2024-01-09 09:51:32 +11:00
2024-01-04 15:41:14 +11:00
2024-01-09 09:54:23 +11:00
2023-04-04 08:31:22 +10:00
2023-12-28 12:03:48 +11:00
2024-01-04 11:42:04 +11:00
2024-01-04 11:42:04 +11:00
2023-12-28 15:48:21 +11:00
2024-01-09 15:28:38 +11:00
2024-01-09 15:28:38 +11:00
2023-12-29 10:58:05 +11:00
2024-01-05 09:48:48 +11:00

title
title
Secrets Management Tool (SMT)

Build Date: {BUILDTIME}

Build Hash: {SHA1VER}

Overview

Provide REST API to store and retrieve secrets with associated username, device name and optionally device class. Secret is stored in sqlite database once encrypted using an AES256 block cipher wrapped in Galois Counter Mode with the standard nonce length.

All secret operations (Create, Read, Update or Delete) require successful authentication. A JWT token is returned upon login, which must be provided for all other operations.

Multiple user roles are supported, with each user only able to access secrets matching their user role. One exception is the built in administrator role that is able to access all secrets.

Written by Nathan Coad (nathan.coad@dell.com)

Installation

  1. Copy binary to chosen location, eg /srv/smt/smt
  2. Create .env file in same directory as binary, populate as per Configuration section below
  3. Create systemd service definition
  4. Start service

Configuration

Environment Variable Name Description Example Default
LOG_FILE Specify the name/path of file to write log messages to /var/log/smt.log ./smt.log
BIND_IP Specify the local IP address to bind to. 127.0.0.1 Primary IPv4 address
BIND_PORT Specify the TCP/IP port to bind to. 443 8443
TLS_KEY_FILE Specify the filename of the TLS certificate private key (must be unencrypted) in PEM format key.pem privkey.pem
TLS_CERT_FILE Specify the filename of the TLS certificate file in PEM format cert.pem cert.pem
TOKEN_HOUR_LIFESPAN Number of hours that the JWT token returned at login is valid 12 No default specified, must define this value
API_SECRET Secret to use when generating JWT token 3c55990bd479322e2053db3a8 No default specified, must define this value
INITIAL_PASSWORD Password to set for builtin Administrator account created when first started, can remove this value after first start. Can specify in plaintext or bcrypt hash $2a$10$s39a82wrRAdOJVZEkkrSReVnXprz5mxU30ZBO.dHPYTncQCsUD9ce password
SECRETS_KEY Key to use for AES256 GCM encryption. Must be exactly 32 bytes AES256Key-32Characters1234567890 No default specified, must define this value or use /api/unlock at runtime

If the TLS certificate and key files cannot be located in the specified location, a self signed certificate will be generated with a 1 year validity period.

Example for generating API_SECRET and SECRETS_KEY is the following command on linux: head /dev/urandom | tr -dc A-Za-z0-9 | head -c32

LDAP specific configuration

Several optional environment variables are available to configure LDAP integration if required. If these parameters are not specifed, LDAP integration will not be used.

If the LDAP_BIND_ADDRESS is specified, SMT will attempt to perform an LDAP search for the provided username if no matches to the locally configured users are found in the database. This search will utilise the provided credentials to perform the LDAP bind.

This lookup will utilise the sAMAccountName property of the user object in Active Directory. No other LDAP providers have been tested.

Upon successfully verifying the LDAP credentials, SMT will verify if any of the group memberships matches a role defined in the SMT database. If no match is found, the authentication will not succeed.

Environment Variable Name Description Example Default
LDAP_BIND_ADDRESS Specify the LDAP Bind address. Only LDAPS on port 636 is supported. Do not specify port 636 in the bind address dc.example.com No default specified
LDAP_BASE_DN Specify the base DN to use when binding to AD "CN=Users,DC=example,DC=com" No default specified
LDAP_TRUST_CERT_FILE Specify filepath to PEM format public certificate of Certificate Authority signing LDAPS communications caroot.pem No default specified, must define this value
LDAP_INSECURE_VALIDATION Specify whether to skip certificate validation when connecting to LDAPS. Do not enable this in production true false

Systemd script

Create/update the systemd service definition at /etc/systemd/system/smt.service and then run systemctl daemon-reload

[Unit]
Description=Secrets Management Tool
After=network.target
#StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/srv/smt/smt

[Install]
WantedBy=multi-user.target

API

Login

POST /api/login

Data

{
    "username": "example_username", 
    "password": "example_password"
}

This API call will return a JWT token that must be present for any other API calls to succeed. The validity duration of this token is based on the configured TOKEN_HOUR_LIFESPAN value. JWT token is returned as value of access_token, and must be supplied via a HTTP header in the form "Authorization: Bearer <JWT_TOKEN>" for all subsequent API calls.

Unlock

POST /api/admin/unlock

Data

{
    "secretKey": "Example32ByteSecretKey0123456789"
}

If the SECRETS_KEY environment variable is not defined, this API call to unlock stored secrets must be performed after initial startup of SMT. Storing/retrieval of secrets will not succeed until this API call has been made.

This API call can only be made once after the service has started. Subsequent calls will receive an error until the service is restarted.

User Operations

Register User

POST /api/admin/user/add

Create a new user record by specifying groupId Body

{
    "userName": "Test User", 
    "password": "Example Password",
    "groupId": "1",
}

Create a new user record by specifying groupName Body

{
    "userName": "Test User", 
    "password": "Example Password",
    "groupName": "Users",
}

Registering a user requires specifying the group to which the user will belong. There are 2 built-in groups, with groupName of 'Administrators' or 'Users' and corresponding groupId of 1 and 2 respectively. Available groups can be retrieved via the /api/admin/groups/list

This operation can only be performed by a user that is a member of a group with the admin flag enabled, or a user who has the admin flag enabled individually on their database record.

Remove User

POST /api/admin/user/delete

Data

{
    "userName": "example_username"
}

This operation can only be performed by a user with a role that is admin enabled. Removes user account corresponding to specified userName.

List Users

GET /api/admin/users

This operation can only be performed by a user with a role that is admin enabled. Lists currently defined users.

Group Operations

List Groups

GET /api/admin/groups/list

This operations has not yet been implemented.

This operation can only be performed by a user with a role that is admin enabled. Lists currently defined groups.

Role Operations - Deprecated

List Roles

GET /api/admin/roles

This operation can only be performed by a user with a role that is admin enabled. Lists currently defined roles.

Create Role

POST /api/admin/role/add

Data

{
    "roleName":"example role",
    "readOnly":true,
    "Admin":false,
    "LdapGroup":"CN=smt_users,OU=Groups,DC=example,DC=com"
}

This operation can only be performed by a user with a role that is admin enabled. Creates a new role. Can be read only, or admin enabled, or map to an LDAP group if LDAP integration is being used.

Users allocated to this role will only be able to access secrets that are part of this role. The exception being users in a role with admin enabled; any user in an admin enabled role can access all secrets.

Ldap group must be specified via the full distinguishedName. The simplest way to get this information is to run the command dsquery group -name <known group name> from a windows machine.

Secrets Operations

Store

POST /api/secret/store

Data

{
    "deviceName": "",
    "deviceCategory": "",
    "userName": "",
    "secretValue": ""
}

Must be logged in to execute this command. Role of current user cannot be a ReadOnly role. Secret will be stored with the RoleId of the currently logged in user. Either deviceName or deviceCategory can be blank but not both.

If a secret exists for this RoleId and matching deviceName and deviceCategory then an error will be generated.

Retrieve

POST /api/secret/retrieve

Data

{
    "deviceName": "",
    "deviceCategory": "",
    "userName": ""
}

Must be logged in to execute this command. Only secrets registered with the current user's RoleId can be retrieved.

Either deviceName or deviceCategory can be specified (or both). Wildcards are supported for both deviceName and deviceCategory fields. userName can also be specified in conjunction with deviceName or deviceCategory.

  1. The percent sign % wildcard matches any sequence of zero or more characters.
  2. The underscore _ wildcard matches any single character.

Search by device name

GET /api/secret/retrieve/name/<searchname>

Search for a secret specified by deviceName using a GET request. Must be logged in to execute this command. Only secrets registered with the current user's RoleId can be retrieved.

Search by device category

GET /api/secret/retrieve/category/<searchname>

Search for a secret specified by deviceCategory using a GET request. Must be logged in to execute this command. Only secrets registered with the current user's RoleId can be retrieved.

Update

POST /api/secret/update

Data

{
    "deviceName": "",
    "deviceCategory": "",
    "userName": "",
    "secretValue": ""
}

Users with ReadOnly role will receive Forbidden error when calling this API endpoint. The values specified in deviceName and deviceCategory must match exactly one existing secret record for the RoleId of the currently logged in user. Wildcards are supported for deviceName and deviceCategory.

List

GET /api/secret/list

Will generate a list of device names and categories but not secret data.

Database Schema

Diagram

Description
No description provided
Readme 2.3 MiB
2024-01-16 15:12:34 +11:00
Languages
Go 80.3%
Shell 9.1%
HTML 5.3%
CSS 5.3%