# Vault
# Resource Paths
Everything in Vault is path-based. Most path identifiers can utilize forward-slash (/
) separators to create hierarchy.
For example, the KV secrets engine is mounted at the /secret
top-level path. Any access to a secret resource in the vault must begin with the /secret
top-level path, followed by lower-specificity path sections to identify the resource.
The most basic secret is a one-level path, such as recipes
. The recipes
secret can be accessed with a path of: /secret/data/recipes
. Thus, a full HTTP API URL to read the recipes
secret is https://vault.example.com:8200/v1/secret/data/recipes
:
curl --insecure --header "X-Vault-Token: <TOKEN>" https://vault.example.com:8200/v1/secret/data/recipes
While working with secrets is the most common task in Vault, everything else is also path-based, including policies, auth methods, and so forth.
# Vault Secret Paths
Solarix Vault adopts a naming scheme similar to Solarix Resource Names (SRN), modified to meet the conventions of Vault's path-based structure and usability. A quick reminder that a SRN is a unique identifier using tags in a lowest-to-highest order of specificity:
srn:service:org[:project][:app][:environment]::resource-type[/resource-id]
Since Vault secrets are much more dynamic than the resources represented by SRNs, naming conventions in Vault can be less strict, but it is strongly recommended to follow some basic conventions:
- Drop the
srn
andservice
tags. Vault secrets are inherently associated with a org/project/app/environment, which is already tied to a specific service within the Solarix architecture. - Use forward-slash (
/
) path tag separators instead of SRN colons (:
). - Explicit
resource-ids
can typically be left out of the secret path and defined as akey
value in the secret data object.
Thus, a Vault Secret Path (VSP) should have the following format, with optional tags shown in brackets ([]
):
org[/project][/app][/environment][/resource-type]
Here are the basic definitions of each tag type with a few examples:
org
Required - Organizational entity. Typically, this is an internal org name, a client name, or individual user name (e.g. solarix, voyager, wcasg, raritan, gabe, kyle, etc).project
Optional - Name of the overall project or internal grouping (e.g. widget, core, etc).app
Optional - Specific application or repository (e.g. domains, dashboard, tracker, connector, etc).environment
Optional - Environment in which this resource resides (e.g. development, testing, staging, or production).resource-type
Optional - Represents the Type of resource (e.g. instance, security group, vpc, subnet, pem, cert, db, cache, etc).
Any further tag specificity can typically be defined as a JSON object key
attached to this secret path.
For example, consider adding a private SSH key for this Hermes documentation project. It belongs to the solarix
organization, is a core
project, and is called the hermes
app. It also has only a single environment of production
. Therefore, the full VSP to store secrets for this resource would be: solarix/core/hermes/production
In the JSON data we can define our private SSH key value:
{
"ssh-private-key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQs8ghShDnbjlcFSQuPBrjAlg+aAxTfaIuQQL6Bz0eqi\nv9LAh9GvYwonJrfYkvU+CR50xhoNlkrZk87zUDNeLrTAZO9y6SwgYnoAyUFmX96\n8+FmoETIUCjoUgAa1A58AAYL4LtwgAv6HGanu3ogyYvl55j9YJCR2BDFKGuyYI\nyzHhzuHO7+eTbaQywpqNqFNaVGXY4HDGwhHtqnAHrz2niEiQi6Dpk+YJDdwQeHIg\n...\n-----END RSA PRIVATE KEY-----"
}
# Policies
Vault Policies are used to define authorization to specified paths.
# Policy Names
A policy should generally assign capabilities to the most specific paths possible. Thus, it should be common practice to name Policies using the Vault Secret Path (VSP) format.
For example, consider a policy that should allow access to READ the private SSH key used in the Hermes production environment. Its VSP is solarix/core/hermes/production
. Therefore, an associated policy might be named solarix/core/hermes/production
as well, and it provides the capability to read
the secret at that same VSP:
vault policy write solarix/core/hermes/production - <<EOF
path "secret/solarix/core/hermes/production" {
capabilities = ["read"]
}
EOF
# JWT/OIDC Roles
# Role Names
Role names cannot use forward-slash (/
) path separators since the Vault engine assumes a role will be a single tag entry within an API path. Therefore, role names should use underscore (_
), period (.
), or dash (-
) path separator characters.
WARNING
It is strongly recommended you use period (.
) path separators for role names.
For example, consider a role that is attached to the Hermes production policy defined above (solarix/core/hermes/production
). The role name should typically follow the same conventions, while replacing forward-slash (/
) separators with periods (.
):
vault write auth/jwt/role/solarix.core.hermes.production - <<EOF
{
"role_type": "jwt",
"policies": ["solarix/core/hermes/production"],
"token_explicit_max_ttl": 60,
"user_claim": "user_email",
"bound_claims": {
"project_id": "65",
"ref": "master",
"ref_type": "branch"
}
}
EOF
# Usage
# Update Local TLS Certificate Stored in Vault
The following illustrates a series of shell commands used to update a local server TLS certificate. The Vault auth method used is userpass. These commands can be combined into a bash script as part of a cron job or issued manually:
USERNAME="certifier"
PASSWORD="1234567890"
SECRET_PATH="certificate/tls/solarix.dev"
VAULT_TOKEN=$(curl --request POST --data "{ \"password\": \"$PASSWORD\" }" https://vault.example.com:8200/v1/auth/userpass/login/$USERNAME | python3 -c "import sys, json; print(json.load(sys.stdin)['auth']['client_token']);")
SECRET=$(curl --location --request GET "https://vault.example.com:8200/v1/secret/data/$SECRET_PATH" --header "X-Vault-Token: $VAULT_TOKEN")
CERTIFICATE=$(echo "$SECRET" | python3 -c "import json, sys; print(json.load(sys.stdin)['data']['data']['cer']);")
KEY=$(echo "$SECRET" | python3 -c "import json, sys; print(json.load(sys.stdin)['data']['data']['key']);")
echo "$CERTIFICATE" > /home/ubuntu/.acme.sh/solarix.dev/fullchain.cer
echo "$KEY" > /home/ubuntu/.acme.sh/solarix.dev/solarix.dev.key
sudo systemctl restart nginx