Compare commits

...

22 Commits

Author SHA1 Message Date
bdddad694b Updated README to include detailed autounseal configuration description. 2026-02-02 21:16:02 +01:00
4c489a05f5 Updated log processing documentation. 2026-01-21 06:58:46 +01:00
742011ca86 Add detailed documentation for identity entities and environment variables 2026-01-20 23:45:04 +01:00
b887ade155 Updates to identity docs. 2026-01-20 19:51:40 +01:00
ba8d65173b Add vault-login script for user authentication 2026-01-20 17:43:37 +01:00
aeb0080f7c Updated TOKEN_ACCESSOR calculation. 2026-01-20 06:59:38 +01:00
b93f47bd6c Add Identity and Authentication documentation 2026-01-19 22:23:20 +01:00
30eaccb1a3 Fix: override default restritive policy for identity admin. 2026-01-19 20:43:39 +01:00
6c5323025b Cleaned up admin policy. 2026-01-19 20:42:56 +01:00
5050963cd5 Update .gitignore to include default_policy.hcl 2026-01-19 20:42:36 +01:00
2c9cb6df90 Update Alloy configuration in README to include log level and tail_from_end setting for audit logs 2026-01-18 17:27:38 +01:00
fe38e97e02 Add auditing section to README with configuration and commands 2026-01-18 12:06:56 +01:00
aca9f4c5ab Add policy files for Vault: admin, app_role, and identity policies 2026-01-18 12:01:42 +01:00
74a364c8e1 Add unwrap and wrap scripts for handling wrapped secrets in Vault 2026-01-18 12:01:29 +01:00
691bcf2bb4 Add auditing configuration check command to README 2026-01-18 12:01:20 +01:00
1034231806 Add VSCode settings for HCL file formatting 2026-01-18 12:01:09 +01:00
54dd1e4e4f Update audit logging instructions and add Alloy configuration for monitoring 2026-01-18 11:55:08 +01:00
dfa2ab5334 Added guide for 1Password CLI integration. 2026-01-08 17:02:45 +01:00
1e96682d79 Add local mode section to README with usage instructions for local Vault instance 2026-01-02 22:54:56 +01:00
a033498d45 Added vault init, destroy, start and unseal scritps. 2026-01-02 22:44:16 +01:00
b116ebab61 Add .gitignore file to exclude configuration, data, log files, and key files 2026-01-02 22:43:37 +01:00
decda15318 Add initial Vault configuration file 2026-01-02 22:43:29 +01:00
20 changed files with 678 additions and 13 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/config
/data
/log
**/*.key
default_policy.hcl

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"[hcl]": {
"editor.tabSize": 2,
"editor.insertSpaces": true
}
}

147
README.md
View File

@@ -37,6 +37,12 @@ export VAULT_ADDR='http://127.0.0.1:8200' VAULT_TOKEN='root-token'
> **Warning:** Development mode is designed for experimentation only. Data is stored in-memory and will be lost when the Vault process is stopped.
## Local Mode
The repository also contains a set of scripts to run a local Vault instance. That instance may be used for experimentation, but unlike the development mode, it uses a file storage backend located at `./data`.
Start it using `bin/vault-start`. The script will create necessary directories and configuration files if they do not exist. The output from the `vault operator init` is saved to `config/vault-init.json`. The single unseal key and the root token are encrypted using GPG key available on the host system. The `bin/vault-unseal` script decrypts the unseal key and unseals the Vault. `set-env` script sets the `VAULT_TOKEN` and `VAULT_ADDR` environment variables. It should be sourced before running any Vault commands.
## TLS Certificate
Use standard Lego ACME installation instructions available at [Let's Encrypt directory](../letsencrypt/README.md) for both the main and the KMS Vault servers.
@@ -89,18 +95,16 @@ The default Vault unseal method uses Shamir's Secret Sharing, which requires man
4. Apply the policy:
```shell
vault policy write transit-unseal-policy transit-unseal-policy.hcl
vault policy write transit-unseal transit_unseal_policy.hcl
```
5. Create a token with the policy attached:
```shell
vault token create -policy="transit-unseal-policy"
vault token create -orphan -policy="transit-unseal" -wrap-ttl=120 -period=24h -field=wrapping_token > wrapping-token.txt
```
Save the generated token for later use.
6. Verify connectivity from the main Vault to the KMS Vault.
6. Copy the `wrapping-token.txt` file securely to the main Vault server. It can be copied using `scp` or any other secure method.
7. Store the KMS Vault unseal key and root token securely. Make an offline backup of the KMS Vault.
@@ -110,9 +114,9 @@ To enhance security and monitoring, enable audit logging on the KMS Vault:
```shell
mkdir -p /var/log/vault
chown -R vault:vault /var/log/vault
chmod 750 /var/log/vault
vault audit enable file file_path=/var/log/vault/audit.log
chown -R vault:adm /var/log/vault
chmod 02750 /var/log/vault
vault audit enable file file_path="/var/log/vault/audit.log" mode="0640"
```
Then monitor the audit log online:
@@ -127,22 +131,80 @@ or offline:
jq -r '. | select(.type == "response") | [ .time, .request.path, .request.operation, .request.remote_address] | @tsv' /var/log/vault/audit.log | column -t -N "time,path,operation,remote_addr"
```
or using Alloy and Grafana. To use Alloy, add the following configuration to `config.alloy`:
```hcl
loki.source.file "vault_audit_log" {
targets = [
{"__path__" = "/var/log/vault/audit.log", "log_name" = "vault_audit"},
]
forward_to = [loki.write.default.receiver]
}
```
Check the auditing configuration:
```shell
vault audit list -detailed
```
### Main Vault Configuration
Depending on main Vault state (new or existing), some of the following steps are mutually exclusive.
1. If the main Vault is already initialized, shut it down and back up its data directory and configuration file.
2. Update the main Vault configuration file (usually located at `/etc/vault.d/vault.hcl`) to include the Auto Unseal configuration:
2. Verify connectivity from the main Vault to the KMS Vault.
```shell
VAULT_ADDR=https://kms.koszewscy.waw.pl:8200 vault status
```
or
```shell
curl -s https://kms.koszewscy.waw.pl:8200/v1/sys/seal-status | jq .
```
3. Update the main Vault configuration file (usually located at `/etc/vault.d/vault.hcl`) to include the Auto Unseal configuration:
```hcl
ui = true
storage "file" {
path = "/opt/vault/data"
}
# HTTP listener
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = "true"
}
# HTTPS listener
listener "tcp" {
address = "192.168.2.10:443"
tls_cert_file = "/opt/vault/tls/tls.crt"
tls_key_file = "/opt/vault/tls/tls.key"
}
seal "transit" {
address = "https://pbs.koszewscy.waw.pl:8200"
key_name = "transit-unseal"
mount_path = "transit/"
address = "https://kms.koszewscy.waw.pl:8200"
disable_renewal = "false"
key_name = "unseal-key"
mount_path = "transit/"
}
```
3. Put the KMS Vault token created earlier into the environment file `/etc/vault.d/vault.env`:
4. Unwrap the token to get the KMS Vault token:
```shell
VAULT_ADDR=https://kms.koszewscy.waw.pl:8200 vault unwrap -field=token $(cat wrapping-token.txt) > kms-vault-token.txt
```
5. Put the unwrapped KMS Vault token into the environment file `/etc/vault.d/vault.env`:
```shell
VAULT_TOKEN="s.xxxxxxx"
@@ -155,6 +217,17 @@ Depending on main Vault state (new or existing), some of the following steps are
EnvironmentFile=/etc/vault.d/vault.env
```
5. Add systemd override `/etc/systemd/system/vault.service.d/override.conf` if not already present:
```ini
[Service]
AmbientCapabilities=CAP_IPC_LOCK CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK CAP_NET_BIND_SERVICE
NoNewPrivileges=yes
```
That will allow the vault process to bind to low-numbered ports (443) and lock memory.
5. If the main Vault was already initialized, start it and unseal with `-migrate` parameter.
```shell
@@ -166,6 +239,8 @@ Depending on main Vault state (new or existing), some of the following steps are
7. Uninitialized main Vault will automatically encrypt the root key with the transit key from the KMS Vault during initialization and present recovery keys for Shamir's Secret Sharing.
If for any reason the Auto Unseal method fails, you can always unseal the main Vault using the recovery keys provided during initialization. If the token expires, generate a new one using the KMS Vault, and transfer it to the main Vault as described above.
## Offline Backup
Vault installs the following directories:
@@ -229,3 +304,49 @@ systemctl start vault
# Unseal the Vault
VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal
```
## 1Password Setup
Install 1Password CLI using the commands below:
```shell
VERSION="v2.32.0" # I don't know how to get the latest version dynamically
# Repleace aarch with arm64
ARCH=${ARCH/aarch64/arm64}
echo "Installing 1Password CLI version ${VERSION} manually..."
TMP="/tmp/$(mktemp -d 1password-cli-installtion.XXXXXX)"
mkdir -p $TMP/extracted
curl -vsSL "https://cache.agilebits.com/dist/1P/op2/pkg/${VERSION}/op_linux_${ARCH}_${VERSION}.zip" -o $TMP/op.zip
unzip $TMP/op.zip -d $TMP/extracted
sudo groupadd -f onepassword-cli
sudo install -g onepassword-cli $TMP/extracted/op /usr/local/bin/op
sudo chmod g+s /usr/local/bin/op
if [[ -d $TMP ]]; then rm -rf $TMP; fi
```
> **Note:** Adjust the `VERSION` variable to install a different version of the 1Password CLI.
Create a `.vault.env` file in the home directory with the following content:
```shell
VAULT_ADDR=http://localhost:8200
VAULT_TOKEN=op://Private/root KMS Koszewscy/password
```
add the following line to your shell profile (e.g., `~/.bashrc` or `~/.zshrc`):
```shell
alias op_vault='op run --env-file="$HOME/.vault.env" -- vault'
```
Run Vault CLI as follows:
```shell
op_vault token lookup
```
Eventually, set both `VAULT_ADDR` and `VAULT_TOKEN` environment variables in your shell:
```shell
export $(cat $HOME/.vault.env | op inject)
```

10
bin/unwrap.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Usage: ./unwrap.sh <VAULT_TOKEN>
# This script unwraps a wrapped secret in HashiCorp Vault using the provided token.
curl -s -X PUT \
-H "X-Vault-Token: $1" \
-H "X-Vault-Request: true" \
-d 'null' \
https://vault.koszewscy.waw.pl/v1/sys/wrapping/unwrap | jq '.data'

7
bin/vault-clear Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -e
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
rm -rf $REPO_ROOT/{config,data,log}

20
bin/vault-init Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
GPG_KEY_ID="slawek@koszewscy.waw.pl"
GPG_PUB_KEY_FILE="$REPO_ROOT/slawek.key"
if [[ ! -f "$GPG_PUB_KEY_FILE" ]]; then
gpg --export "$GPG_KEY_ID" > "$GPG_PUB_KEY_FILE"
fi
# Initialize the Vault and store the initialization output in a JSON file
# The single unseal key and the root token will be PGP-encrypted using the provided GPG public key
VAULT_ADDR='http://127.0.0.1:8200' vault operator init \
-key-shares=1 \
-key-threshold=1 \
-pgp-keys="$GPG_PUB_KEY_FILE" \
-root-token-pgp-key="$GPG_PUB_KEY_FILE" \
-format=json > $REPO_ROOT/config/vault-init.json

17
bin/vault-login Executable file
View File

@@ -0,0 +1,17 @@
# Check, if we are sourced, that's a requirement for this script
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "This script must be sourced, not executed directly."
echo "Use: source bin/vault-login"
exit 1
fi
# v_login function may be added to .bashrc, .zprofile, etc.
function v_login() {
local VAULT_USERNAME=${1:-adminslawek}
vault login -format=json -method=userpass username="$VAULT_USERNAME" |
jq -r '.auth | [.client_token, .accessor] | @tsv' | read -r VAULT_TOKEN TOKEN_ACCESSOR
echo "Logged in as $VAULT_USERNAME (Token accessor: $TOKEN_ACCESSOR)"
export VAULT_TOKEN TOKEN_ACCESSOR
}
v_login "$@"

12
bin/vault-start Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
mkdir -p $REPO_ROOT/{config,data,log}
sed -e "s|{{VAULT_DATA_DIR}}|$REPO_ROOT/data|g" \
-e "s|{{VAULT_LOG_DIR}}|$REPO_ROOT/log|g" \
$REPO_ROOT/vault.hcl > $REPO_ROOT/config/vault.hcl
vault server -config=$REPO_ROOT/config/vault.hcl -log-file=$REPO_ROOT/log/vault.log

9
bin/vault-unseal Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. && pwd)"
UNSEAL_KEY_ENC=$(jq -r .unseal_keys_b64[0] $REPO_ROOT/config/vault-init.json)
vault operator unseal $(echo "$UNSEAL_KEY_ENC" | base64 -d | gpg -qd)
VAULT_ADDR='http://127.0.0.1:8200'

10
bin/wrap.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
DEFAULT_TTL="60"
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--header "X-Vault-Wrap-TTL: $DEFAULT_TTL" \
--request POST \
--data "$1" \
$VAULT_ADDR/v1/sys/wrapping/wrap | jq

69
docs/ENV_VARS.md Normal file
View File

@@ -0,0 +1,69 @@
# Environment Variables
> Note: This list was generated by an AI Agent from a limited code search of the repository and may be incomplete.
>
> For the full code search results, see: https://github.com/hashicorp/vault/search?q=VAULT_&type=code.
| Environment Variable | Purpose (short) |
|-------------------------------------------|-------------------------------------------------------------------------|
| `VAULT_ADDR` | Client/server address (API target) |
| `VAULT_AGENT_ADDR` | Agent address (deprecated usage/const) |
| `VAULT_ALLOW_PENDING_REMOVAL_MOUNTS` | Allow Pending Removal builtins to be mounted |
| `VAULT_CACERT_BYTES` | CA certificate bytes provided via env |
| `VAULT_CACERT` | CA certificate file for TLS verification |
| `VAULT_CAPATH` | CA path for TLS verification |
| `VAULT_CLI_NO_COLOR` | Toggle colored CLI output |
| `VAULT_CLIENT_CERT` | Client TLS certificate path |
| `VAULT_CLIENT_KEY` | Client TLS key path |
| `VAULT_CLIENT_TIMEOUT` | Client timeout configuration |
| `VAULT_CLUSTER_ADDR` | Cluster address for inter-node comms |
| `VAULT_CLUSTER_INTERFACE` | Interface name used to derive VAULT_CLUSTER_ADDR |
| `VAULT_DETAILED` | Output detailed CLI information |
| `VAULT_DEV_LISTEN_ADDRESS` | Dev-mode listen address (entrypoint default) |
| `VAULT_DEV_ROOT_TOKEN_ID` | Dev-mode root token ID (used by entrypoint) |
| `VAULT_DISABLE_FILE_PERMISSIONS_CHECK` | Disable strict file permission checks (OpenShift/UBI entrypoint) |
| `VAULT_DISABLE_LOCAL_AUTH_MOUNT_ENTITIES` | Disable entities for local auth mounts via env |
| `VAULT_DISABLE_REDIRECTS` | Disable HTTP redirects for client |
| `VAULT_DISABLE_RSA_DRBG` | Disable RSA DRBG path in cryptoutil (feature flag) |
| `VAULT_ENABLE_RATE_LIMIT_AUDIT_LOGGING` | Enable audit logging for rate-limited rejections |
| `VAULT_EXPERIMENTS` | Comma-separated experiments enabled on startup |
| `VAULT_FORMAT` | CLI output format |
| `VAULT_HEADERS` | Additional headers for API client |
| `VAULT_HTTP_PROXY` | HTTP proxy configuration for client |
| `VAULT_LDAP_PASSWORD` | LDAP password fallback for CLI LDAP credential provider |
| `VAULT_LICENSE_CI` | CI license helper for tests |
| `VAULT_LICENSE_PATH` | Path to enterprise license file |
| `VAULT_LICENSE` | Provide enterprise license blob |
| `VAULT_LOCAL_CONFIG` | Pass Vault JSON config via env (entrypoint writes to config dir) |
| `VAULT_LOG_FORMAT` | Control logger format (standard/json) |
| `VAULT_LOG_LEVEL` | Logging level for Vault |
| `VAULT_MAX_RETRIES` | Max retries for client operations |
| `VAULT_MESSAGE_TYPE` | Serialization format for forwarded requests (json/json_compress/proto3) |
| `VAULT_MFA` | MFA selection for client |
| `VAULT_MYSQL_PASSWORD` | MySQL password override for physical MySQL backend |
| `VAULT_MYSQL_USERNAME` | MySQL username override for physical MySQL backend |
| `VAULT_NAMESPACE` | Default namespace header for client requests |
| `VAULT_PLUGIN_AUTOMTLS_ENABLED` | Enable plugin AutoMTLS (plugin helper) |
| `VAULT_PLUGIN_METADATA_MODE` | Control plugin metadata bootstrapping mode |
| `VAULT_PLUGIN_TMPDIR` | Folder for Unix sockets for containerized plugins |
| `VAULT_POSTUNSEAL_FUNC_CONCURRENCY` | Concurrency for post-unseal functions (sets worker count) |
| `VAULT_PROXY_ADDR` | Proxy address configuration |
| `VAULT_RAFT_DISABLE_MAP_POPULATE` | Disable MAP_POPULATE behaviour on Linux |
| `VAULT_RAFT_FREELIST_SYNC` | BoltDB freelist sync toggle |
| `VAULT_RAFT_FREELIST_TYPE` | BoltDB freelist type (array/map) |
| `VAULT_RAFT_INITIAL_MMAP_SIZE` | Initial mmap size for Bolt DB |
| `VAULT_RAFT_MAX_BATCH_ENTRIES` | Override Raft max batch entries |
| `VAULT_RAFT_MAX_BATCH_SIZE_BYTES` | Override Raft max batch size bytes |
| `VAULT_RAFT_NODE_ID` | Raft node ID from environment |
| `VAULT_RAFT_PATH` | Raft data path from environment |
| `VAULT_RAFT_RETRY_JOIN_AS_NON_VOTER` | Join Raft as non-voter via env |
| `VAULT_RATE_LIMIT` | Configure client-side or server rate limiting |
| `VAULT_REDIRECT_ADDR` | API redirect address (can be set directly) |
| `VAULT_REDIRECT_INTERFACE` | Interface name used to derive VAULT_REDIRECT_ADDR |
| `VAULT_SKIP_LOGGING_LEASE_EXPIRATIONS` | Toggle logging of lease expirations |
| `VAULT_SKIP_VERIFY` | Skip TLS verification (insecure) |
| `VAULT_SRV_LOOKUP` | Enable SRV DNS lookup behavior |
| `VAULT_TLS_SERVER_NAME` | TLS server name for verification |
| `VAULT_TOKEN` | Default Vault token for client auth |
| `VAULT_UNWRAP_TOKEN` | Pass unwrap tokens to plugin (plugin helper) |
| `VAULT_WRAP_TTL` | Default wrap TTL for client operations |

140
docs/Identity.md Normal file
View File

@@ -0,0 +1,140 @@
# Identity and Authentication
## Token Authentication
Setup `VAULT_ADDR` and `VAULT_TOKEN` environment variables to authenticate with Vault using a token.
Store the root token in 1Password and retrieve it when needed using CLI commands.
```bash
export OP_VAULT_TOKEN="op://Private/root Vault Koszewscy/password"
export VAULT_ADDR="https://vault.koszewscy.waw.pl" VAULT_TOKEN="${OP_VAULT_TOKEN}"
```
Then, run the vault using:
```bash
op run -- vault login $VAULT_TOKEN
```
1Password CLI will fetch the token from the specified path in your 1Password vault and replace the secret reference with the actual token value when executing the command. However, that method adds a delay due to the `op run` command.
Alternatively, you can directly set the `VAULT_TOKEN` environment variable by reading the token from 1Password:
```bash
export VAULT_TOKEN=$(op read "op://Private/root Vault Koszewscy/password")
```
With VAULT_TOKEN set, `vault` authenticates directly.
## Userpass Authentication Method
### Login with Userpass
Userpass authentication allows users to log in with a username and password.
```bash
vault login -method=userpass username="your-username"
```
The token is stored in a file located at `~/.vault-token` by default. Although, the token file is secured with file permissions, it contains a plaintext token. Change the token time-to-live (TTL) to limit its validity period.
```bash
vault write auth/userpass/users/your-username max_token_ttl="12h" token_ttl="1h"
```
Limit the token's usage to known IP addresses for added security.
```bash
vault write auth/userpass/users/your-username token_bound_cidrs="192.168.2.0/24"
```
You can also set VAULT_TOKEN with the following command:
```bash
export VAULT_TOKEN=$(vault login -token-only -method=userpass username="your-username")
```
or a function like this:
```bash
function v_login() {
local VAULT_USERNAME=${1:-"your-username"}
vault login -format=json -method=userpass username="$VAULT_USERNAME" |
jq -r '.auth | [.client_token, .accessor] | @tsv' | read -r VAULT_TOKEN TOKEN_ACCESSOR
echo "Logged in as $VAULT_USERNAME (Token accessor: $TOKEN_ACCESSOR)"
export VAULT_TOKEN TOKEN_ACCESSOR
}
```
> **Note:** The `-token-only` is an equivalent of `-field=token -no-store` options.
You can then use the `TOKEN_ACCESSOR` to look up token details without exposing the actual token.
```bash
vault token lookup -accessor $TOKEN_ACCESSOR
```
Use the `vault token renew` command to renew the token before it expires.
```bash
vault token renew
```
### User Management
List all users:
```bash
vault list auth/userpass/users
```
Create a new user:
```bash
vault write auth/userpass/users/new-username password="new-password" policies="default"
```
> **Note:** key="value" pairs may contain scalars or lists (comma-separated values).
Read user details:
```bash
vault read auth/userpass/users/username
```
## Entities and Groups
### Entities
Docs: [https://developer.hashicorp.com/vault/api-docs/secret/identity/entity](https://developer.hashicorp.com/vault/api-docs/secret/identity/entity)
List entities by id:
```bash
vault list identity/entity/id
```
or by name:
```bash
vault list identity/entity/name
```
[Read entity details by id](https://developer.hashicorp.com/vault/api-docs/secret/identity/entity#read-entity-by-id)
or [by name](https://developer.hashicorp.com/vault/api-docs/secret/identity/entity#read-entity-by-name):
```bash
vault read identity/entity/id/<entity-id>
vault read identity/entity/name/<entity-name>
```
[Create a new entity](https://developer.hashicorp.com/vault/api-docs/secret/identity/entity#create-an-entity):
```bash
vault write identity/entity name="entity-name" policies="default" metadata=key1=value1 metadata=key2=value2
```
### Entity Aliases
Docs: [https://developer.hashicorp.com/vault/api-docs/secret/identity/entity-alias](https://developer.hashicorp.com/vault/api-docs/secret/identity/entity-alias)

39
docs/README.md Normal file
View File

@@ -0,0 +1,39 @@
# General Vault Links and Commands
## Useful commands
Display the `curl` equivalent of a Vault CLI command:
```bash
vault <any_command> -output-curl-string
```
The following are equivalent:
```bash
curl -s -H "X-Vault-Request: true" -H "X-Vault-Token: $VAULT_TOKEN" "https://vault.koszewscy.waw.pl/v1/auth/userpass/users?list=true"
```
and
```bash
curl -s -X LIST -H "X-Vault-Request: true" -H "X-Vault-Token: $VAULT_TOKEN" https://vault.koszewscy.waw.pl/v1/auth/userpass/users
```
because the Vault uses non-standard HTTP method `LIST` for listing resources.
## Environment Variables
| Environment Variable | Purpose (short) |
|-------------------------------------------|-------------------------------------------------------------------------|
| `VAULT_ADDR` | Client/server address (API target) |
| `VAULT_DETAILED` | Output detailed CLI information |
| `VAULT_FORMAT` | CLI output format |
| `VAULT_LOG_FORMAT` | Control logger format (standard/json) |
| `VAULT_LOG_LEVEL` | Logging level for Vault |
| `VAULT_TOKEN` | Default Vault token for client auth |
| `VAULT_UNWRAP_TOKEN` | Pass unwrap tokens to plugin (plugin helper) |
| `VAULT_WRAP_TTL` | Default wrap TTL for client operations |
> The list above is a small subset of all available environment variables, that I see most useful.
> The rest can be found in the [ENV_VARS.md](ENV_VARS.md) file.

97
policies/README.md Normal file
View File

@@ -0,0 +1,97 @@
# HashiCorp Vault Policies
## Defualt Policy
The **default** policy is created automatically when Vault is initialized, but can be modified as needed. It provides basic access to Vault features for authenticated users.
To restore the default policy to the newest default version, launch a development Vault server and copy the default policy from there:
```bash
vault policy read default > default_policy.hcl
vault policy write default default_policy.hcl
```
## Policy Commands
```bash
vault policy list
vault policy read <policy-name>
vault policy write <policy-name> <policy-file.hcl>
vault policy delete <policy-name>
```
Format a policy file using `vault policy fmt <policy-file.hcl>`.
Display required capabilities for a given path with:
```bash
vault <anycommand> -output-policy
```
## Auditing
To enable auditing, use the following command:
```bash
vault audit enable file file_path=/var/log/vault_audit.log mode=0640
```
Configure Alloy to read the audit logs from the specified file path.
Add the following configuration to your Alloy setup:
```hcl
loki.source.file "vault_audit_log" {
targets = [
{"__path__" = "/var/log/vault/audit.log", "log_name" = "vault_audit", "level" = "info", "service" = "vault"},
]
tail_from_end = true
forward_to = [loki.process.vault_audit.receiver]
}
loki.process "vault_audit" {
stage.json {
expressions = {error = "error"}
}
stage.labels {
values = { __has_error = "error" }
}
stage.match {
selector = "{__has_error!=\"\"}"
stage.static_labels {
values = {level = "error"}
}
}
stage.label_drop {
values = ["__has_error"]
}
forward_to = [loki.write.default.receiver]
}
```
> **Note:** `tail_from_end = true` ensures that only new log entries are read, preventing the ingestion of old lines/entries.
> It is (probably) required because the audit log file does not contain timestamps and only entry guids.
> Without this setting, Alloy may re-ingest old log entries upon restart.
>
> `loki.process` extracts message level from the `error` field in the JSON log entry.
Check auditing configuration with:
```bash
vault audit list -detailed
```
To disable auditing, use:
```bash
vault audit disable file
```
## References
- [RSoP Tool](https://github.com/threatkey-oss/hvresult) - **hvresult** computes the Resultant Set of Policy (RSoP) for Hashicorp Vault ACLs.

43
policies/admin_policy.hcl Normal file
View File

@@ -0,0 +1,43 @@
# Read system health check
path "sys/health" {
capabilities = ["read", "sudo"]
}
# Create and manage ACL policies broadly across Vault
# List existing policies
path "sys/policies/acl" {
capabilities = ["list"]
}
# Create and manage ACL policies
path "sys/policies/acl/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# Enable and manage authentication methods broadly across Vault
# Manage auth methods broadly across Vault
path "auth/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# Create, update, and delete auth methods
path "sys/auth/*" {
capabilities = ["create", "update", "delete", "sudo"]
}
# List auth methods
path "sys/auth" {
capabilities = ["read"]
}
# Manage secrets engines
path "sys/mounts/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# List existing secrets engines.
path "sys/mounts" {
capabilities = ["read"]
}

View File

@@ -0,0 +1,19 @@
# Mount the AppRole auth method
path "sys/auth/approle" {
capabilities = [ "create", "read", "update", "delete", "sudo" ]
}
# Configure the AppRole auth method
path "sys/auth/approle/*" {
capabilities = [ "create", "read", "update", "delete" ]
}
# Create and manage roles
path "auth/approle/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
# Write ACL policies
path "sys/policies/acl/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}

View File

@@ -0,0 +1,13 @@
# Add identity admin role to the token
path "identity/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
# Override default policies for identity management
path "identity/entity/id/{{identity.entity.id}}" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "identity/entity/name/{{identity.entity.name}}" {
capabilities = ["create", "read", "update", "delete", "list"]
}

View File

@@ -0,0 +1,7 @@
path "transit/decrypt/unseal-key" {
capabilities = ["update"]
}
path "transit/encrypt/unseal-key" {
capabilities = ["update"]
}

10
set-env Normal file
View File

@@ -0,0 +1,10 @@
# Check, if we have been sourced
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "This script must be sourced, not executed!" >&2
exit 1
fi
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN=$(jq -r .root_token config/vault-init.json | base64 -d | gpg -qd)

11
vault.hcl Normal file
View File

@@ -0,0 +1,11 @@
ui = true
disable_mlock = true
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
storage "file" {
path = "{{VAULT_DATA_DIR}}"
}