WL#12974: Frontend for MySQL Routers keyring

Affects: Server-8.0   —   Status: Complete

Motivation

MySQL Router can store the passwords in a keyring at bootstrap.

The keyring is secured by either

  • master key provided via stdin or
  • master-key-file or
  • an external key utility

master-key-file and external-key-utility get the absolute filename of the keyfile as key to retrieve keyring-key.

User Stories

  1. As Router Admin I want to add or change the password that's used by the router to update it after it has been expired on the server.
  2. As Router Admin I want to move router installation to a new location.
  3. As Router Admin I want to add new accounts to the keyring to unify accounts used by the router after bootstrap.
  4. As Router Admin I want to remove account from the keyring that aren't used anymore.

Goal

Allow to

  • list the accounts stored in the keyring
  • remove accounts from the keyring
  • change password of accounts in the keyring
  • change the filename location in the master-keyring
FR1
All commands which accept --master-key-reader or --master-key-writer MUST fail if --master-key-file is also specified.
FR2
if decryption fails, list, get, export MUST fail.
FR3
if --master-key-file is specified list, get, export MUST fail if keyring does not exist
FR4
empty usernames MUST fail.
FR5
empty property-keys MUST fail.

Cmd: init

FR6
if the keyring does not exist init MUST create it
FR7
if --master-key-file is specified init MUST create a master-key-file if it doesn't exist
FR8
if --master-key-file is specified, init MUST add the encrypted keyring-key to the master-key-file.
FR9
if --master-key-writer is specified, init MUST pass the keyring-key to the provided executable.

Cmd: list

FR10
if --master-key-file is specified, list MUST fail if master-key-file does not exist
FR11
if only filename is provided, list MUST print the usernames stored in the keyring.
FR12
if filename and username are provided and username exists in the keyring, list MUST print the property names stored in the keyring for that username.
FR13
if filename and username are provided and username does not exist in the keyring, list MUST fail.

Cmd: get

FR14
if filename, username and property-key are provided and the property-key exists for the user in the keyring, get MUST print the value of the property that's stored in the keyring for that username.
FR15
if filename, username and property-key are provided and the property-key does not exists for the user in the keyring, get MUST fail.
FR16
if filename, username and property-key are provided and the username does not exists in the keyring, get MUST fail.

Cmd: export

FR17
if filename is provided export MUST print the decrypted content of the keyring as JSON to stdout

Cmd: set

FR18
if filename, username, property-key and value are provided, set MUST set the property and create username if it does not exist already in the keyring.

Cmd: delete

FR19
if filename, username and property-key are provided and username and property-key exist, delete MUST delete the property of that user from the keyring.
FR20
if filename, username and property-key are provided and username or property-key do not exist, delete MUST fail.
FR21
if filename and username are provided, but no property-key, and username exist in the keyring delete MUST delete the user from the keyring.
FR22
if filename and username are provided, but no property-key, and username does not exist in the keyring delete MUST fail.

Cmd: master-key-list

FR23
if master-key-file is provided and exists, master-key-list MUST print the ids to stdout.

Cmd: master-key-delete

FR23
if master-key-file is provided and exists, and key-id is provided and exists , master-key-delete MUST delete the entry from the master-key-file.

Cmd: master-key-rename

FR24
if master-key-file is provided and exists, and key-id is provided and exists, and new-key-id is not empty, master-key-rename MUST rename the entry in the master-key-file.

Background

keyring and master-key-file

The keyring is stored in data/keyring of the router datadir and contains:

keyring_random
a 32-byte salt
enc_keyring
an encrypted dictionary of key-value pairs per username

The dictionary of the keyring is AES-256-CBC encrypted based on a key stored

  • externally with via --master-key-reader/--master-key-writer
  • in a master-key-file mysqlrouter.key

The master-key-file is a persisted array of {id, enc_keyring_key}:

id
absolute keyring-filename
enc_keyring_key
enc_keyring_key = AES_256_CBC_enc(keyring_key, keyring_random, iv)

Interface

Generic commands

help

Get the usage help on stdout:

$ mysqlrouter_keyring --help

version

Get the version information on stdout:

$ mysqlrouter_keyring --version

Keyring commands

master-key-reader/writer

All commands accept --master-key-reader and --master-key-writer instead of --master-key-file.

init

Initialize keyring with master-key-file:

$ mysqlrouter_keyring init --master-key-file=mysqlrouter.key data/keyring
  • creates keyring if it doesn't exist
  • creates master-key-file if it doesn't exist
  • adds keyring to master-key-file if it isn't existing in master-key-file

list

List usernames stored in keyring to stdout.

$ mysqlrouter_keyring list --master-key-file=mysqlrouter.key data/keyring

List properties of a user stored in keyring to stdout.

$ mysqlrouter_keyring list --master-key-file=mysqlrouter.key data/keyring user

get

Get property of user from keyring and print to stdout.

$ mysqlrouter_keyring get --master-key-file=mysqlrouter.key data/keyring someuser key

export

Export the keyring as JSON to stdout.

$ mysqlrouter_keyring export --master-key-file=mysqlrouter.key data/keyring

set

Set a property in keyring

$ mysqlrouter_keyring get --master-key-file=mysqlrouter.key data/keyring user key value

If value is not provided, it will be read from stdin.

delete

Delete a user from the keyring:

$ mysqlrouter_keyring delete --master-key-file=mysqlrouter.key data/keyring user

Delete a property of a user from the keyring:

$ mysqlrouter_keyring delete --master-key-file=mysqlrouter.key data/keyring user key

Master-key commands

master-key-list

List keyring-ids from master-key-file to stdout:

$ mysqlrouter_keyring master-key-list --master-key-file=mysqlrouter.key

master-key-delete

Delete master-key for "keyring" from master-key-file:

$ mysqlrouter_keyring master-key-delete --master-key-file=mysqlrouter.key data/keyring 

master-key-rename

Rename the keyring-id in a master-key-file:

$ mysqlrouter_keyring master-key-rename --master-key-file=mysqlrouter.key data/keyring other/data/keyring
The code should be developed as two components:
  1. library that does all the keyring manipulation
  2. command-line wrapper executable that calls appropriate library functions