A Hubot script to grant temporary access to MySQL databases using HashiCorp's Vault. If the MySQL database is hosted in AWS RDS, this script also provides with the option to grant temporary access to the database security group from the user's current IP.
As said, this script uses Vault API under the hood, providing an abstraction layer thanks to Hubot. So in order to make things work you'll need an operative Vault server, and properly configured. See How to configure Vault
I've only tested this script with the Slack and Shell adapters, but it should work with most adapters.
hubot give me <level> access to <database> database
The level
corresponds to the Vault role you want to use to access the specified database
. A useful pattern would be to have readonly
and readwrite
levels, and different databases for different environments, so you could do something like this:
hubot give me readonly access to production database
hubot set vault token [for <user> ] <token>
This command sets a Vault token for the sender user or for the specified user. Note that only admins can set tokens for other users. See hubot-auth.
hubot reset vault token [for <user> ]
This removes a stored Vault token for the sender user or from the specified user. As with the set command, only admins can reset tokens for other users.
npm i hubot-db-heimdall --save
And then add "hubot-db-heimdall"
to the external-scripts.json
file.
This Hubot script uses node-config module to manage the configuration of the different parameters. If your Hubot already uses node-config
, you only need to add the corresponding configuration under the hubot-db-heimdall
atribute in your config file. If thats not the case, then you only need to create the file config/default.js
in the root of your project with the content described below.
The minimum configuration for this script to work is:
module.exports = {
'hubot-db-heimdall': {
Urls: {
vault_base_url: "https://vault.example.com:8200"
},
Databases: [{...}]
}
};
You'll also want to add at least one database definition. See Configuring the databases.
For each database that you want to manage through this script, you'll need to add an object like this to the Databases
array in the configuration parameters.
{
name: 'production',
rds_security_group: 'db-production',
matcher: /prod(?:uction)?/i,
vault_mount: 'db_production',
vault_roles: [
{
name: 'readonly',
matcher: /ro|readonly|read/i
}, {
name: 'readwrite',
matcher: /rw|readwrite|write/i
}, {
name: 'admin',
matcher: /admin/i
}
]
}
Where:
name
- only for reference in hubot responses.
matcher
- A regular expression to match the Hubot command with the desired database.
vault_mount
- The vault mount that this database uses, that is the first segment of the Vault path to retrieve the credentials (e.g.: db_production/creds/readonly).
vault_roles
- All the roles that Vault accepts for this database (i.e.: Vault mount). A Vault role definition has two components: the name
is the actual name of the Vault role used, that's the last part of the Vault path (e.g.: db_production/creds/readonly); and the matcher
is the regular expression that will be used to match the role in the Hubot command.
rds_security_group
- (optional) AWS RDS security group for the database. See Configure access to AWS RDS security groups.
This script uses Vault's MySQL secret backend to generate the proper credentials, follow this guide to know how to setup a MySQL mount with at least one role.
If the MySQL database that you want to manage through Hubot is hosted in AWS RDS, this script also has the ability to grant temporary access to the database security group through the requesting user's IP. To achieve this, when a user requests access to a database, Hubot will send him a link that he'll need to access through the web browser. This way Hubot knows the user's IP and can allow it in the RDS database security group. This access is also temporary and will be revoked automatically by Hubot when the Vault credentials lease time expires.
To enable this functionality, you need to provide valid AWS credentials with the following permissions:
- rds:AuthorizeDBSecurityGroupIngress
- rds:DescribeDBSecurityGroups
- rds:RevokeDBSecurityGroupIngress
This script uses the official AWS SDK for Node.js, so any of the authentication methods described here will work correctly. But if you want to provide specific credentials for this script only, without interfering with other Hubot scripts, you can set the following configuration parameters:
module.exports = {
'hubot-db-heimdall': {
AWS: {
aws_access_key_id: "blablablabla",
aws_secret_access_key: "blablablabla"
},
Urls: {...},
Databases: [...]
}
};
You'll also need to provide your Hubot server base url with the base_url
configuration atribute under the Urls
section, like so:
{
Urls: {
base_url: "https://ubot.example.net/",
vault_base_url: "https://vault.example.com:8200"
}
}
Finally you'll need to set the rds_security_group
configuration atribute for each database that you want to manage this way.