-
Notifications
You must be signed in to change notification settings - Fork 98
AWS SecretsManager
This guide shows how to setup a KES server that uses AWS SecretsManager as a persistent key store protected by the AWS-KMS:
╔═══════════════════════════════════════════════════╗
┌────────────┐ ║ ┌────────────┐ ┌─────────────────────┐ ║
│ KES Client ├───────────╫──┤ KES Server ├──────────┤ AWS Secrets-Manager │ ║
└────────────┘ ║ └────────────┘ └──────────┬──────────┘ ║
╚═════════════════════════════════════╪═════════════╝
|
┌─────┴─────┐
| AWS-KMS |
└───────────┘
The AWS SecretsManager is basically a key-value store for secrets - like passwords, access tokens and cryptographic keys. AWS will encrypt these secrets via their AWS-KMS service.
To create, retrieve and delete secrets at/from the AWS SecretsManager you need an AWS IAM user - i.e. an AWS access key and AWS secret key pair with sufficient IAM policy permissions. If you already have an IAM user / the access key and secret key, you can skip the following to steps:
- Go to the AWS console and create a new user.
Use the
Programmatic access
type to create a new access key / secret key pair. - Attach policies to that user to grant access to the AWS SecretsManager and the AWS-KMS.
AWS has predefined policies (
SecretsManagerReadWrite
andAWSKeyManagementServicePowerUser
) that will work but also grant a lot of permissions that are not needed. Your AWS IAM user needs to have to following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1578498399136",
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "Stmt1578498562539",
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
],
"Effect": "Allow",
"Resource": "*"
}
]
}
Note that this example policy grants access to all KMS and SecretsManager resources. You can restrict that by specifying a AWS ARN as resource instead
*
.
First, we need to generate a TLS private key and certificate for our KES server. A KES server can only be run with TLS - since secure-by-default. Here we use self-signed certificates for simplicity. For a production setup we highly recommend to use a certificate signed by CA (e.g. your internal CA or a public CA like Let's Encrypt)
-
First, create the TLS private key:
openssl ecparam -genkey -name prime256v1 | openssl ec -out server.key
-
Then, create the corresponding TLS X.509 certificate:
openssl req -new -x509 -days 30 -key server.key -out server.cert \ -subj "/C=/ST=/L=/O=/CN=localhost" -addext "subjectAltName = IP:127.0.0.1"
-
Now you have a server.key and server.cert file. Next, we create the root identity:
kes tool identity new --key=root.key --cert=root.cert root
Note that we create a private key (
root.key
) and a certificate (root.cert
) for TLS client authentication. Again, the certificate is not signed by a CA that is trusted by the KES server. That is not a security issue per se since only clients with public keys/certificates that are known to the server can perform operations based on policies. However, we recommend to use client certificates that were issued by a trusted CA. Then the KES server does not even accept connections from untrusted clients.You can compute the root identity via:
kes tool identity of root.cert
-
Since we don't want to give our applications root capabilities we also create an
app
identity:kes tool identity new --key=app.key --cert=app.cert app
You can compute the
app
identity via:kes tool identity of app.cert
-
Now we have defined all entities in our demo setup. Let's wire everything together by creating the config file
server-config.yml
:address: 0.0.0.0:7373 root: <kes-tool-identity-of root.cert> tls: key : server.key cert: server.cert policy: my-app: paths: - /v1/key/create/my-app* - /v1/key/generate/my-app* - /v1/key/decrypt/my-app* identities: - <kes-tool-identity-of app.cert> keys: aws: secretsmanager: endpoint: secretsmanager.us-east-2.amazonaws.com # Use the SecretsManager in your region. region: us-east-2 # Use your region kmskey: "" # Your AWS-KMS master key (CMK) - optional. credentials: accesskey: "" # Your AWS Access Key secretkey: "" # Your AWS Secret Key
Please use your own root and app identity and access key / secret key pair.
-
Finally we can start a KES server in a new window/tab:
kes server --config=server-config.yml --auth=off
--auth=off
is required since our root.cert and app.cert certificates are self-signed -
In the previous window/tab we now can connect to the server by:
export KES_CLIENT_TLS_CERT_FILE=app.cert export KES_CLIENT_TLS_KEY_FILE=app.key kes key create app-key -k
-k
is required because we use self-signed certificatesNow, you should see a secret key inside the
./keys
directory. -
Finally, we can derive and decrypt data keys from the previously created
app-key
:kes key derive app-key -k { plaintext : ... ciphertext: ... }
kes key decrypt app-key -k <base64-ciphertext>