Merge branch 'main' into fix/file-descriptor-leak-on-chown-error

This commit is contained in:
Abhishek Dadwal 2026-06-07 02:22:23 +05:30 committed by GitHub
commit 96e447e23f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1923 changed files with 79544 additions and 29962 deletions

View file

@ -2,21 +2,25 @@ schema_version = 1
project {
license = "BUSL-1.1"
copyright_year = 2025
copyright_year = 2016
copyright_holder = "IBM Corp."
ignore_year1 = true
# (OPTIONAL) A list of globs that should not have copyright/license headers.
# Supports doublestar glob patterns for more flexibility in defining which
# files or folders should be ignored
header_ignore = [
".git/**",
"enos/.enos/**",
"enos/.terraform/**",
"enos/k8s/.enos/**",
"enos/modules/k8s_deploy_vault/raft-config.hcl",
"enos/modules/zap_scan_ent/templates/plan.yml",
"helper/pkcs7/**",
"plugins/database/postgresql/scram/**",
"tools/pipeline/internal/pkg/generate/fixtures/*",
"ui/node_modules/**",
"ui/pnpm-lock.yaml",
"ui/pnpm-workspace.yaml",
"enos/modules/k8s_deploy_vault/raft-config.hcl",
"plugins/database/postgresql/scram/**",
"enos/.enos/**",
"enos/k8s/.enos/**",
"enos/.terraform/**",
]
}

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
.git
enos

View file

@ -1,4 +1,4 @@
# Copyright IBM Corp. 2016, 2025
# Copyright IBM Corp. 2016, 2026
# SPDX-License-Identifier: BUSL-1.1
self-hosted-runner:
@ -8,14 +8,9 @@ self-hosted-runner:
- medium
- large
- xlarge
- ondemand
- disk_gb=64
- os=linux
- os=ubuntu-arm
- type=m5.2xlarge
- type=c6a.xlarge
- type=c6g.2xlarge
- type=c6a.4xlarge
- type=c6g.2xlarge;c6g.4xlarge
- ubuntu-latest-x64
- ubuntu-22.04-x64
- ubuntu-22.04-x64
- ubuntu-24.04-arm64
- custom-linux-xl-vault-latest
- stats
- type=m6a.8xlarge

57
.github/actions/build-ui/action.yml vendored Normal file
View file

@ -0,0 +1,57 @@
# Copyright IBM Corp. 2016, 2026
# SPDX-License-Identifier: BUSL-1.1
---
name: Build UI
description: |
Build the Vault Web UI assets and cache the results.
inputs:
github-token:
description: An elevated Github token to access private dependencies if necessary.
default: ""
outputs:
cache-key:
description: "The cache key for the built UI assets (format: ui-<git-hash>)"
value: ${{ steps.ui-hash.outputs.cache-key }}
cache-hit:
description: "Whether the UI was restored from cache (true) or built fresh (false)"
value: ${{ steps.cache-ui-assets.outputs.cache-hit }}
runs:
using: composite
steps:
- name: Get UI hash
id: ui-hash
shell: bash
run: |
ui_hash=$(git ls-tree HEAD ui --object-only)
echo "cache-key=ui-${ui_hash}" | tee -a "$GITHUB_OUTPUT"
- name: Set up UI asset cache
id: cache-ui-assets
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
enableCrossOsArchive: true
lookup-only: true
path: http/web_ui
# Only restore the UI asset cache if we haven't modified anything in the ui directory.
# Never do a partial restore of the web_ui if we don't get a cache hit.
key: ${{ steps.ui-hash.outputs.cache-key }}
- name: Install PNPM
if: ${{ steps.cache-ui-assets.outputs.cache-hit != 'true' }}
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
run_install: false
package_json_file: './ui/package.json'
- name: Set up node and pnpm
if: ${{ steps.cache-ui-assets.outputs.cache-hit != 'true' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: ui/package.json
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- name: Build UI
if: ${{ steps.cache-ui-assets.outputs.cache-hit != 'true' }}
shell: bash
run: make ci-build-ui

View file

@ -69,7 +69,7 @@ runs:
shell: bash
run: git config --global url."https://${{ inputs.github-token }}:@github.com".insteadOf "https://github.com"
- name: Restore UI from cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
# Restore the UI asset from the UI build workflow. Never use a partial restore key.
enableCrossOsArchive: true
@ -117,7 +117,7 @@ runs:
id: build-vault-select-license
uses: hashicorp-forge/actions-pao-tool/select-license@6997f7457c338e008506005cc370e7b02f7fb421 # v1.0.3
with:
arch: ${{ matrix.goarch }}
arch: ${{ inputs.goarch }}
- if: inputs.cgo-enabled == '0'
name: ${{ steps.metadata.outputs.build-step-name }}
env:
@ -133,7 +133,7 @@ runs:
shell: bash
run: make ci-build
- if: inputs.cgo-enabled == '1'
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
driver-opts: network=host # So we can run our own little registry
- if: inputs.cgo-enabled == '1'
@ -143,7 +143,7 @@ runs:
if: inputs.cgo-enabled == '1'
id: build-push-action-attempt-1
continue-on-error: true # we will retry this if it fails
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
env:
DOCKER_BUILD_SUMMARY: false
with:
@ -165,7 +165,7 @@ runs:
id: build-push-action-attempt-2
continue-on-error: false
if: inputs.cgo-enabled == '1' && steps.build-push-action-attempt-1.outcome != 'success'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
env:
DOCKER_BUILD_SUMMARY: false
with:
@ -218,12 +218,16 @@ runs:
BUNDLE_PATH: out/${{ steps.metadata.outputs.artifact-basename }}.zip
shell: bash
run: make ci-bundle
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.metadata.outputs.artifact-basename }}.zip
path: out/${{ steps.metadata.outputs.artifact-basename }}.zip
if-no-files-found: error
- if: inputs.create-packages == 'true'
env:
# Use our elevated token instead of the workflow token so that our
# download of nfpm is less likely to fail.
GH_TOKEN: ${{ inputs.github-token }}
uses: hashicorp/actions-packaging-linux@33f7d23b14f24e6a7b7d9948cb7f5caca2045ee3
with:
name: ${{ inputs.package-name }}
@ -250,13 +254,13 @@ runs:
echo "deb-files=$(basename out/*.deb)"
} | tee -a "$GITHUB_OUTPUT"
- if: inputs.create-packages == 'true'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.package-files.outputs.rpm-files }}
path: out/${{ steps.package-files.outputs.rpm-files }}
if-no-files-found: error
- if: inputs.create-packages == 'true'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.package-files.outputs.deb-files }}
path: out/${{ steps.package-files.outputs.deb-files }}

View file

@ -20,26 +20,21 @@ runs:
id: dyn-cfg-metadata
shell: bash
run: |
# Since the dynamic config is created by a specific version of the
# pipeline tool, we always need to factor it into our cache key.
# If the pipeline changes we always want to make sure we are using
# dynamic config from the latest version.
# The cache key is a short SHA of the enos-dynamic-config.tmpl file.
# We also include a weekly date in the cache key so that we regenerate
# the configuration on at least a weekly basis to account for changing
# versions. If we add more templates to this we ought to consider their
# short sha's in the key too!
#
# We use a weekly date in the cache key so that we regenerate the
# configuration on at least a weekly basis
#
# If/when Github decides to purge our tiny config file cache we'll also
# recreate it as necessary.
#
# Uses GITHUB_ENV instead of GITHUB_OUTPUT because composite actions are broken,
# see: https://github.com/actions/cache/issues/803#issuecomment-1793565071
# Uses GITHUB_ENV instead of GITHUB_OUTPUT because composite actions are
# broken, see: https://github.com/actions/cache/issues/803#issuecomment-1793565071
{
echo "DYNAMIC_CONFIG_KEY=${{ inputs.vault-version }}-$(date +%Y-%m-%U)-$(git ls-tree HEAD tools/pipeline --object-only --abbrev=8)"
echo "DYNAMIC_CONFIG_KEY=${{ inputs.vault-version }}-$(date +%Y-%m-%U)-$(git ls-tree HEAD enos/enos-dynamic-config.tmpl --object-only --abbrev=8)"
echo "DYNAMIC_CONFIG_PATH=enos/enos-dynamic-config.hcl"
} | tee -a "$GITHUB_ENV"
- name: Try to restore dynamic config from cache
id: dyn-cfg-cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ env.DYNAMIC_CONFIG_PATH }}
key: dyn-cfg-${{ env.DYNAMIC_CONFIG_KEY }}
@ -56,9 +51,8 @@ runs:
shell: bash
run: |
# Make sure that any branch specific dynamic config has been generated
pipeline generate enos-dynamic-config ${{ runner.debug && '--log debug' }}\
-d ./enos \
--file enos-dynamic-config.hcl \
-v ${{ inputs.vault-version }} \
-e ${{ inputs.vault-edition }} \
-n 3
pipeline generate template ${{ runner.debug && '--log debug' }} \
enos/enos-dynamic-config.tmpl \
enos/enos-dynamic-config.hcl \
--version '${{ inputs.vault-version }}' \
--edition '${{ inputs.vault-edition }}'

View file

@ -69,7 +69,7 @@ runs:
echo "VAULT_TOOLS_CACHE_KEY=${cache_key}"
} | tee -a "$GITHUB_ENV"
- id: cache-tools
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
lookup-only: ${{ inputs.no-restore }}
path: ${{ env.VAULT_TOOLS_PATH }}

View file

@ -156,9 +156,11 @@ runs:
if [ "$is_enterprise_repo" = 'true' ]; then
base_ref='${{ github.event.pull_request.base.ref || github.event.base_ref || github.ref_name || github.event.branch || github.ref }}'
is_ent_repo='true'
is_ce_in_enterprise=$([[ $base_ref == ce/* ]] && echo "true" || echo "false")
is_ent_branch='true'
is_ce_in_enterprise=$([[ $base_ref == ce/* || $base_ref == refs/heads/ce/* ]] && echo "true" || echo "false")
if [ "$is_ce_in_enterprise" = 'true' ]; then
is_enterprise="false"
is_ent_branch="false"
go_tags=''
version_metadata='${{ inputs.vault-version }}'
else
@ -166,10 +168,10 @@ runs:
go_tags='ent,enterprise'
version_metadata='${{ inputs.vault-version }}+ent'
fi
compute_build='["self-hosted","ondemand","os=linux","disk_gb=64","type=c6a.4xlarge;c5a.4xlarge"]'
compute_build_ui='["self-hosted","ondemand","os=linux","disk_gb=64","type=c6a.2xlarge;c5a.2xlarge;c6a.4xlarge"]'
compute_test_go='["self-hosted","ondemand","os=linux","disk_gb=64","type=c6a.2xlarge;c5a.2xlarge;c6a.4xlarge"]'
compute_test_ui='["self-hosted","ondemand","os=linux","type=m6a.2xlarge;m6a.4xlarge"]'
compute_build='["self-hosted","ubuntu-22.04-x64"]'
compute_build_ui='["self-hosted","ubuntu-22.04-x64"]'
compute_test_go='["self-hosted","ubuntu-22.04-x64"]'
compute_test_ui='["self-hosted","ubuntu-22.04-x64"]'
compute_small='["self-hosted","linux","small"]'
else
compute_build='"custom-linux-medium-vault-latest"'
@ -191,7 +193,7 @@ runs:
echo "compute-small=${compute_small}"
echo "go-tags=${go_tags}"
echo "is-ce-in-enterprise=${is_ce_in_enterprise}"
echo "is-ent-branch=${is_enterprise}"
echo "is-ent-branch=${is_ent_branch}"
echo "is-ent-repo=${is_ent_repo}"
echo "vault-version-metadata=${version_metadata}"
} | tee -a "$GITHUB_OUTPUT"

View file

@ -0,0 +1,114 @@
# run-enos-scenario
Reusable composite action for running an Enos scenario with standardized retry, debug artifact upload, and destroy cleanup behavior.
## Behavior
The action performs this lifecycle:
1. Optionally installs Terraform.
2. Optionally installs Enos.
3. Prepares a sanitized debug artifact name from the scenario filter.
4. Runs `enos scenario launch`.
5. Retries the launch command once if the first attempt fails.
6. Optionally prints `enos scenario exec --cmd show` and `plan` before retry and after a failed retry.
7. Uploads debug data on failure.
8. Always destroys the scenario and retries destroy once if needed.
## Inputs
| Name | Required | Default | Description |
| --- | --- | --- | --- |
| `scenario-filter` | yes | n/a | Scenario filter passed to Enos. |
| `working-directory` | no | `./enos` | Value passed to `--chdir`. |
| `timeout` | no | `45m0s` | Timeout for the first main command attempt. |
| `retry-timeout` | no | `30m0s` | Timeout for the retry attempt. |
| `destroy-timeout` | no | `10m0s` | Timeout for destroy. |
| `show-state-on-retry` | no | `false` | When `true`, prints scenario state and plan before retry and after failed retry. |
| `upload-debug-data` | no | `true` | When `true`, uploads debug data on failure. |
| `debug-data-retention-days` | no | `30` | Artifact retention days for debug data. |
| `debug-data-path` | no | empty | Explicit debug data directory. If empty, uses `ENOS_DEBUG_DATA_ROOT_DIR` or `/tmp/enos-debug-data`. |
| `setup-terraform` | no | `true` | When `true`, installs Terraform. |
| `setup-enos` | no | `true` | When `true`, installs Enos. |
| `launch-extra-args` | no | empty | Extra arguments added to the launch command before the scenario filter. |
| `retry-extra-args` | no | empty | Extra arguments added to the retry launch command before the scenario filter. |
| `destroy-extra-args` | no | empty | Extra arguments added to destroy before the scenario filter. |
| `pre-destroy-command` | no | empty | Optional enos scenario command to run before destroying (e.g., `exec`). |
| `pre-destroy-extra-args` | no | empty | Extra arguments added to the pre-destroy command before the scenario filter. |
## Outputs
| Name | Description |
| --- | --- |
| `launch-outcome` | Final main phase outcome: `success` or `failure`. |
| `launch-retry-attempted` | `true` when the main phase retry was attempted. |
| `destroy-outcome` | Final destroy outcome: `success` or `failure`. |
| `destroy-retry-attempted` | `true` when destroy retry was attempted. |
| `debug-data-artifact-name` | Sanitized debug artifact name derived from the scenario filter. |
| `debug-data-dir` | Debug data directory used by the action. |
| `error-message` | Failure message captured from the retry step, when present. |
## Usage
### Standard launch workflow
```yaml
- name: Run Enos scenario
id: run-scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ matrix.scenario.id.filter }}
timeout: 45m0s
retry-timeout: 30m0s
destroy-timeout: 10m0s
show-state-on-retry: 'true'
```
### With custom destroy arguments
```yaml
- name: Run Enos scenario
id: run-scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ inputs.scenario }}
timeout: 60m0s
retry-timeout: 60m0s
destroy-timeout: 60m0s
destroy-extra-args: --grpc-listen http://localhost
```
### Skip tool installation
```yaml
- name: Run Enos scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ steps.sample.outputs.filter }}
setup-terraform: 'false'
setup-enos: 'false'
```
### With pre-destroy command
```yaml
- name: Run Enos scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ inputs.scenario }}
timeout: 30m0s
pre-destroy-command: exec
pre-destroy-extra-args: --cmd 'output -raw scan_markdown'
```
### With pre-destroy command and output redirection
```yaml
- name: Run Enos scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ inputs.scenario }}
timeout: 30m0s
pre-destroy-command: exec
pre-destroy-extra-args: --cmd 'output -raw scan_markdown' | tee -a "$GITHUB_STEP_SUMMARY"
```

View file

@ -0,0 +1,266 @@
# Copyright IBM Corp. 2016, 2026
# SPDX-License-Identifier: BUSL-1.1
---
name: Run and retry an Enos scenario
description: |
Run an Enos scenario with a standard launch retry flow, optional state/plan diagnostics,
automatic debug data artifact naming, and destroy cleanup with a destroy retry.
inputs:
scenario-filter:
description: Enos scenario filter/identifier (for example "ui edition:ent backend:raft")
required: true
working-directory:
description: Working directory to pass to enos via --chdir
required: false
default: ./enos
timeout:
description: Timeout for the initial launch command
required: false
default: 45m0s
retry-timeout:
description: Timeout for the retry launch attempt
required: false
default: 30m0s
destroy-timeout:
description: Timeout for the destroy command
required: false
default: 10m0s
show-state-on-retry:
description: Whether to show scenario state and plan before and after a failed retry (true/false)
required: false
default: 'false'
upload-debug-data:
description: Whether to upload Enos debug data on failure (true/false)
required: false
default: "true"
debug-data-retention-days:
description: Retention period in days for uploaded debug data artifacts
required: false
default: "30"
debug-data-path:
description: Debug data root directory to create and upload
required: false
default: ""
setup-terraform:
description: Whether to install Terraform in the action (true/false)
required: false
default: "true"
setup-enos:
description: Whether to install Enos in the action (true/false)
required: false
default: "true"
launch-extra-args:
description: Extra arguments to append to the launch command before the scenario filter
required: false
default: ""
retry-extra-args:
description: Extra arguments to append to the retry launch command before the scenario filter
required: false
default: ""
destroy-extra-args:
description: Extra arguments to append to the destroy command before the scenario filter
required: false
default: ""
pre-destroy-command:
description: Optional enos scenario command to run before destroying (e.g., "exec")
required: false
default: ""
pre-destroy-extra-args:
description: Extra arguments to append to the pre-destroy command before the scenario filter
required: false
default: ""
outputs:
launch-outcome:
description: Final execution outcome for the main phase (success or failure)
value: ${{ steps.determine-launch-outcome.outputs.outcome }}
launch-retry-attempted:
description: Whether a retry was attempted for the main phase
value: ${{ steps.determine-launch-outcome.outputs.retry-attempted }}
destroy-outcome:
description: Final destroy outcome (success or failure)
value: ${{ steps.determine-destroy-outcome.outputs.outcome }}
destroy-retry-attempted:
description: Whether a destroy retry was attempted
value: ${{ steps.determine-destroy-outcome.outputs.retry-attempted }}
debug-data-artifact-name:
description: Debug data artifact name prepared by the action
value: ${{ steps.prepare-artifacts.outputs.debug-data-artifact-name }}
debug-data-dir:
description: Debug data directory prepared by the action
value: ${{ steps.prepare-artifacts.outputs.debug-data-dir }}
error-message:
description: Error message captured from a failed retry
value: ${{ steps.launch-retry.outputs.error-message }}
runs:
using: composite
steps:
- if: inputs.setup-terraform == 'true'
name: Setup Terraform
uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
with:
terraform_wrapper: false
- if: inputs.setup-enos == 'true'
name: Setup Enos
uses: hashicorp/action-setup-enos@6ec106c8f809fe645162d73bea565c65f3269907 # v1.52
- id: prepare-artifacts
name: Prepare artifacts and debug directory
shell: bash
run: |
artifact_name="enos-debug-data_$(echo "${{ inputs.scenario-filter }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')"
debug_dir="${{ inputs.debug-data-path }}"
if [ -z "${debug_dir}" ]; then
debug_dir="${ENOS_DEBUG_DATA_ROOT_DIR:-/tmp/enos-debug-data}"
fi
mkdir -p "${debug_dir}"
{
echo "debug-data-artifact-name=${artifact_name}"
echo "debug-data-dir=${debug_dir}"
} | tee -a "$GITHUB_OUTPUT"
- id: launch
name: Run Enos scenario
continue-on-error: true
shell: bash
run: |
enos scenario launch \
--timeout ${{ inputs.timeout }} \
${{ inputs.launch-extra-args }} \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }}
- if: steps.launch.outcome == 'failure' && inputs.show-state-on-retry == 'true'
name: Show scenario state before retry
shell: bash
run: |
echo "::group::Scenario state before retry"
enos scenario exec --cmd show \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} || true
echo "::endgroup::"
echo "::group::Scenario plan before retry"
enos scenario exec --cmd plan \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} || true
echo "::endgroup::"
- if: steps.launch.outcome == 'failure'
id: launch-retry
name: Retry Enos scenario
shell: bash
run: |
if ! output=$(enos scenario launch \
--timeout ${{ inputs.retry-timeout }} \
${{ inputs.retry-extra-args }} \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} 2>&1); then
if [ "${{ inputs.show-state-on-retry }}" = "true" ]; then
echo "::group::Scenario state after retry"
enos scenario exec --cmd show \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} || true
echo "::endgroup::"
echo "::group::Scenario plan after retry"
enos scenario exec --cmd plan \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} || true
echo "::endgroup::"
fi
echo "::group::Scenario retry failure"
echo "$output" >&2
{
echo "# Enos Scenario Failed!"
echo 'See the [workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more information'
echo '```'
echo "$output"
echo '```'
} | tee -a "$GITHUB_STEP_SUMMARY"
echo "::endgroup::"
exit 1
fi
- id: determine-launch-outcome
name: Determine launch outcome
shell: bash
run: |
retry_attempted=false
if [ "${{ steps.launch.outcome }}" = "failure" ]; then
retry_attempted=true
fi
if [ "${{ steps.launch.outcome }}" = "success" ] || [ "${{ steps.launch-retry.outcome }}" = "success" ]; then
outcome=success
else
outcome=failure
fi
{
echo "outcome=${outcome}"
echo "retry-attempted=${retry_attempted}"
} | tee -a "$GITHUB_OUTPUT"
- if: failure() && inputs.upload-debug-data == 'true'
name: Upload debug data
continue-on-error: true
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.prepare-artifacts.outputs.debug-data-artifact-name }}
path: ${{ steps.prepare-artifacts.outputs.debug-data-dir }}
retention-days: ${{ inputs.debug-data-retention-days }}
- if: always() && inputs.pre-destroy-command != ''
id: pre-destroy
name: Run pre-destroy command
continue-on-error: true
shell: bash
run: |
enos scenario ${{ inputs.pre-destroy-command }} \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }} \
${{ inputs.pre-destroy-extra-args }}
- if: always()
id: destroy
name: Destroy Enos scenario
continue-on-error: true
shell: bash
run: |
enos scenario destroy \
--timeout ${{ inputs.destroy-timeout }} \
${{ inputs.destroy-extra-args }} \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }}
- if: steps.destroy.outcome == 'failure'
id: destroy-retry
name: Retry Enos scenario destroy
continue-on-error: true
shell: bash
run: |
enos scenario destroy \
--timeout ${{ inputs.destroy-timeout }} \
${{ inputs.destroy-extra-args }} \
--chdir ${{ inputs.working-directory }} \
${{ inputs.scenario-filter }}
- if: always()
id: determine-destroy-outcome
name: Determine destroy outcome
shell: bash
run: |
retry_attempted=false
if [ "${{ steps.destroy.outcome }}" = "failure" ]; then
retry_attempted=true
fi
if [ "${{ steps.destroy.outcome }}" = "success" ] || [ "${{ steps.destroy-retry.outcome }}" = "success" ]; then
outcome=success
else
outcome=failure
fi
{
echo "outcome=${outcome}"
echo "retry-attempted=${retry_attempted}"
} | tee -a "$GITHUB_OUTPUT"

View file

@ -40,7 +40,7 @@ runs:
else
echo "go-version=${{ inputs.go-version }}" | tee -a "$GITHUB_OUTPUT"
fi
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: ${{ steps.go-version.outputs.go-version }}
cache: false # We use our own caching strategy
@ -63,7 +63,7 @@ runs:
echo "cache-key=go-modules-${wd_hash}-${{ hashFiles('**/go.sum') }}"
} | tee -a "$GITHUB_OUTPUT"
- id: cache-modules
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
enableCrossOsArchive: true
lookup-only: ${{ inputs.no-restore }}

View file

@ -33,7 +33,7 @@ runs:
} | tee -a "$GITHUB_ENV"
- name: Try to restore pipeline from cache
id: pipeline-cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ env.PIPELINE_PATH }}
key: pipeline-${{ env.PIPELINE_HASH }}

32
.github/actions/setup-pnpm/action.yml vendored Normal file
View file

@ -0,0 +1,32 @@
# Copyright IBM Corp. 2016, 2025
# SPDX-License-Identifier: BUSL-1.1
# This action will set up Node and then install pnpm dependencies, which might be restored from cache if available.
# In case of a cache miss, pnpm dependencies will be installed and later be stored in the "post step" of actions/cache.
---
name: Setup pnpm
description: Setup Node and install pnpm
runs:
using: composite
steps:
- name: Install PNPM
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
run_install: false
package_json_file: './ui/package.json'
- name: Setup Node Caching
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: './ui/package.json'
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- name: Install UI dependencies
working-directory: ./ui
shell: bash
run: |
pnpm i
pnpm rebuild node-sass

View file

@ -11,7 +11,7 @@ This document provides Handlebars template coding standards for HashiCorp Ember.
## Template Best Practices
- Check truthiness of arrays directly instead of using `.length` property
- Use string interpolation `"prefix/{{value}}"` instead of `{{concat}}` helper
- Use string interpolation `"prefix/{{value}}"` instead of `{{concat}}` helper
- Remove unnecessary quotes around dynamic component arguments
- Use `Hds::Link::Inline` for external documentation links instead of `<button>` elements
- Make `selected` attributes dynamic rather than static values - warn if static values are used
@ -19,6 +19,7 @@ This document provides Handlebars template coding standards for HashiCorp Ember.
- Avoid inline `style` attributes and `{{style ...}}` helpers - define CSS classes in `.scss` files instead
- Place `data-test-*` selectors as the last attribute on elements
- Remove quotes around dynamic data attributes: `data-test-id={{value}}` not `data-test-id="{{value}}"`
- **Avoid shadowed elements**: Avoid HTML element names (like `option`, `input`, `select`, etc.) as block parameter names in `{{#each}}` loops to prevent `no-shadowed-elements` lint errors and broken functionality.
Examples:
```handlebars
@ -64,6 +65,20 @@ Examples:
{{!-- Bad: unnecessary quotes --}}
<div data-test-namespace-link="{{option.label}}">
{{!-- Good: avoid shadowed elements by using descriptive block parameter names --}}
{{#each @field.options as |opt|}}
<option selected={{eq @value opt.value}} value={{opt.value}}>
{{opt.label}}
</option>
{{/each}}
{{!-- Bad: using HTML element name as block parameter causes lint error --}}
{{#each @field.options as |option|}}
<option selected={{eq @value option.value}} value={{option.value}}>
{{option.label}}
</option>
{{/each}}
```
---

View file

@ -12,8 +12,12 @@ MAX_TESTS=10
[ "${PR_NUMBER:?}" ]
[ "${RESULT:?}" ]
table_data() {
if [ -z "$TABLE_DATA" ]; then
# Function to format table data for a specific test type
format_table_data() {
local data="$1"
local test_type="$2"
if [ -z "$data" ]; then
return 0
fi
@ -21,45 +25,80 @@ table_data() {
# Only keep the test type, test package, test name, and logs column
# Remove the scroll emoji
# Remove "github.com/hashicorp/vault" from the package name
TABLE_DATA=$(echo "$TABLE_DATA" | awk -F\| '{if ($4 != " - ") { print "|" $2 "|" $3 "|" $4 "|" $7 }}' | sed -r 's/ :scroll://' | sed -r 's/github.com\/hashicorp\/vault\///')
NUM_FAILURES=$(wc -l <<< "$TABLE_DATA")
local formatted_data=$(echo "$data" | awk -F\| '{if ($4 != " - ") { print "|" $2 "|" $3 "|" $4 "|" $7 }}' | sed -r 's/ :scroll://' | sed -r 's/github.com\/hashicorp\/vault\///')
local num_failures=$(echo "$formatted_data" | wc -l)
# Check if the number of failures is greater than the maximum tests to display
# If so, limit the table to MAX_TESTS number of results
if [ "$NUM_FAILURES" -gt "$MAX_TESTS" ]; then
TABLE_DATA=$(echo "$TABLE_DATA" | head -n "$MAX_TESTS")
NUM_OTHER=( "$NUM_FAILURES" - "$MAX_TESTS" )
TABLE_DATA="${TABLE_DATA}
if [ "$num_failures" -gt "$MAX_TESTS" ]; then
formatted_data=$(echo "$formatted_data" | head -n "$MAX_TESTS")
local num_other=$(( num_failures - MAX_TESTS ))
formatted_data="${formatted_data}
and ${NUM_OTHER[*]} other tests"
and ${num_other} other tests"
fi
# Add the header for the table
printf "%s" "Failures:
| Test Type | Package | Test | Logs |
| --------- | ------- | ---- | ---- |
${TABLE_DATA}"
${formatted_data}"
}
td="$(table_data)"
case "$RESULT" in
success)
if [ -z "$td" ]; then
BODY="CI Results:
All Go tests succeeded! :white_check_mark:"
else
BODY="CI Results:
All required Go tests succeeded but failures were detected :warning:
${td}"
fi
;;
*)
BODY="CI Results: ${RESULT} :x:
${td}"
;;
esac
source ./.github/scripts/gh-comment.sh
update_or_create_comment "$REPO" "$PR_NUMBER" "CI Results:" "$BODY"
# Separate enos failures from other test failures
if [ -n "$TABLE_DATA" ]; then
ENOS_DATA=$(echo "$TABLE_DATA" | grep "^| enos |" || true)
OTHER_DATA=$(echo "$TABLE_DATA" | grep -v "^| enos |" || true)
else
ENOS_DATA=""
OTHER_DATA=""
fi
# Create comment for regular test failures (non-enos)
if [ -n "$OTHER_DATA" ]; then
other_td="$(format_table_data "$OTHER_DATA" "other")"
case "$RESULT" in
success)
OTHER_BODY="CI Results - Go Tests:
All required Go tests succeeded but failures were detected :warning:
${other_td}"
;;
*)
OTHER_BODY="CI Results - Go Tests: ${RESULT} :x:
${other_td}"
;;
esac
update_or_create_comment "$REPO" "$PR_NUMBER" "CI Results - Go Tests:" "$OTHER_BODY"
fi
# Create separate comment for enos failures
if [ -n "$ENOS_DATA" ]; then
enos_td="$(format_table_data "$ENOS_DATA" "enos")"
case "$RESULT" in
success)
ENOS_BODY="CI Results - Enos Tests:
All required Enos tests succeeded but failures were detected :warning:
${enos_td}"
;;
*)
ENOS_BODY="CI Results - Enos Tests: ${RESULT} :x:
${enos_td}"
;;
esac
update_or_create_comment "$REPO" "$PR_NUMBER" "CI Results - Enos Tests:" "$ENOS_BODY"
fi
# If no failures at all, create a single success comment
if [ -z "$OTHER_DATA" ] && [ -z "$ENOS_DATA" ]; then
if [ "$RESULT" == "success" ]; then
SUCCESS_BODY="CI Results:
All Go tests succeeded! :white_check_mark:"
update_or_create_comment "$REPO" "$PR_NUMBER" "CI Results:" "$SUCCESS_BODY"
fi
fi

View file

@ -12,7 +12,7 @@ concurrency:
jobs:
actionlint:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: "Run actionlint"

View file

@ -17,7 +17,7 @@ jobs:
add-hashicorp-contributed-label:
# Only run if this is NOT coming from a fork of hashicorp/vault (if this is not true, it's community contributed)
if: ${{ github.repository == 'hashicorp/vault' && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
# gh pr edit needs a .git directory so we'll do a shallow checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

View file

@ -13,7 +13,7 @@ on:
jobs:
bench:
name: Bench
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

View file

@ -83,7 +83,7 @@ jobs:
github.event_name == 'push' ||
github.event_name == 'schedule' ||
(github.event_name == 'pull_request' && github.event.pull_request.draft == false)
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all # vault-auth
outputs:
build-date: ${{ steps.metadata.outputs.vault-build-date }}
@ -186,7 +186,7 @@ jobs:
startsWith(github.event.pull_request.base.ref, 'ce/')
runs-on:
- self-hosted
- ubuntu-latest-x64
- ubuntu-22.04-x64
permissions: write-all # vault-auth
needs:
- setup
@ -293,40 +293,13 @@ jobs:
needs: setup
runs-on: ${{ fromJSON(needs.setup.outputs.compute-build-ui) }}
outputs:
cache-key: ui-${{ steps.ui-hash.outputs.ui-hash }}
cache-key: ${{ steps.build-ui.outputs.cache-key }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ needs.setup.outputs.checkout-ref }}
- name: Get UI hash
id: ui-hash
run: echo "ui-hash=$(git ls-tree HEAD ui --object-only)" | tee -a "$GITHUB_OUTPUT"
- name: Set up UI asset cache
id: cache-ui-assets
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
enableCrossOsArchive: true
lookup-only: true
path: http/web_ui
# Only restore the UI asset cache if we haven't modified anything in the ui directory.
# Never do a partial restore of the web_ui if we don't get a cache hit.
key: ui-${{ steps.ui-hash.outputs.ui-hash }}
- if: steps.cache-ui-assets.outputs.cache-hit != 'true'
name: Install PNPM
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
with:
run_install: false
package_json_file: './ui/package.json'
- if: steps.cache-ui-assets.outputs.cache-hit != 'true'
name: Set up node and pnpm
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ui/package.json
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- if: steps.cache-ui-assets.outputs.cache-hit != 'true'
name: Build UI
run: make ci-build-ui
- uses: ./.github/actions/build-ui
id: build-ui
# Artifacts is where we'll build the various Vault binaries and package them into their respective
# Zip bundles, RPM and Deb packages, and container images. After we've packaged them we upload
@ -392,23 +365,75 @@ jobs:
web-ui-cache-key: ${{ needs.ui.outputs.cache-key }}
secrets: inherit
# Setup HCP input parameters with proper validation
hcp-setup:
runs-on: ubuntu-latest
outputs:
pull-request-number: ${{ steps.pr-logic.outputs.pull-request-number }}
branch-name: ${{ steps.branch-logic.outputs.branch-name }}
steps:
- id: pr-logic
name: Determine pull request number
run: |
echo "Analyzing PR context for event: ${{ github.event_name }}"
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
PR_NUM="${{ github.event.pull_request.number }}"
if [[ -n "$PR_NUM" && "$PR_NUM" != "null" ]]; then
echo "PR context detected, using number: $PR_NUM"
else
echo "PR context but no valid number found, using 0"
PR_NUM="0"
fi
else
PR_NUM="0"
echo "Non-PR context, using fallback value: $PR_NUM"
fi
echo "pull-request-number=$PR_NUM" >> "$GITHUB_OUTPUT"
- id: branch-logic
name: Determine branch name
run: |
echo "Analyzing branch context for event: ${{ github.event_name }}"
if [[ "${{ github.event_name }}" == "schedule" ]]; then
BRANCH="main"
echo "Schedule context, using branch: $BRANCH"
else
BRANCH=""
echo "Non-schedule context, using empty branch"
fi
echo "branch-name=$BRANCH" >> "$GITHUB_OUTPUT"
hcp-image:
# Logic: Run HCP image job if:
# if needs.setup.outputs.is-ent-branch != 'true' then
# false
# elseif needs.setup.outputs.workflow-trigger == 'schedule' then
# true
# elseif needs.setup.outputs.workflow-trigger == 'pull_request' and (
# contains(fromJSON(needs.setup.outputs.changed-files).groups, 'hcp') or
# contains(fromJSON(needs.setup.outputs.labels), 'hcp/build-image') or
# contains(fromJSON(needs.setup.outputs.labels), 'hcp/test')
# ) then
# true
# end
if: |
needs.setup.outputs.is-ent-branch == 'true' &&
needs.setup.outputs.workflow-trigger == 'schedule' ||
( needs.setup.outputs.is-ent-branch != 'true' ) && false ||
( needs.setup.outputs.workflow-trigger == 'schedule' ) && true ||
( needs.setup.outputs.workflow-trigger == 'pull_request' &&
(
( contains(fromJSON(needs.setup.outputs.changed-files).groups, 'hcp') ||
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'hcp') ||
contains(fromJSON(needs.setup.outputs.labels), 'hcp/build-image') ||
contains(fromJSON(needs.setup.outputs.labels), 'hcp/test')
)
)
) && true
needs:
- setup
- artifacts-ent
- hcp-setup
uses: ./.github/workflows/build-hcp-image.yml
with:
pull-request: ${{ needs.setup.outputs.workflow-trigger == 'pull_request' && github.event.pull_request.number || '' }}
branch: ${{ needs.setup.outputs.workflow-trigger == 'schedule' && 'main' || '' }}
pull-request: ${{ fromJSON(needs.hcp-setup.outputs.pull-request-number) }}
branch: ${{ needs.hcp-setup.outputs.branch-name }}
create-aws-image: true
create-azure-image: false
hcp-environment: int
@ -433,7 +458,7 @@ jobs:
include: ${{ needs.setup.outputs.is-ent-branch == 'true' && fromJSON(needs.artifacts-ent.outputs.testable-packages) || fromJSON(needs.artifacts-ce.outputs.testable-packages) }}
with:
build-artifact-name: ${{ matrix.artifact }}
runs-on: ${{ github.repository == 'hashicorp/vault' && '"ubuntu-latest"' || '["self-hosted","ubuntu-latest-x64"]' }}
runs-on: ${{ github.repository == 'hashicorp/vault' && '"ubuntu-latest"' || '["self-hosted","ubuntu-22.04-x64"]' }}
sample-max: 1
sample-name: ${{ matrix.sample }}
ssh-key-name: ${{ github.event.repository.name }}-ci-ssh-key
@ -473,11 +498,17 @@ jobs:
# Test our custom HCP image if our image build was successful and we've
# been configured with the correct label.
if: |
needs.setup.outputs.is-ent-branch == 'true' &&
needs.setup.outputs.workflow-trigger == 'pull_request' &&
needs.artifacts-ent.result == 'success' &&
needs.hcp-image.result == 'success' &&
contains(fromJSON(needs.setup.outputs.labels), 'hcp/test')
needs.setup.outputs.is-ent-branch == 'true' && (
( needs.setup.outputs.workflow-trigger == 'pull_request' &&
needs.artifacts-ent.result == 'success' &&
needs.hcp-image.result == 'success' &&
( contains(fromJSON(needs.setup.outputs.changed-files).groups, 'hcp') || contains(fromJSON(needs.setup.outputs.labels), 'hcp/test') )
) || (
needs.setup.outputs.workflow-trigger == 'schedule' &&
needs.artifacts-ent.result == 'success' &&
needs.hcp-image.result == 'success'
)
)
needs:
- setup
- artifacts-ent
@ -502,7 +533,7 @@ jobs:
github.event_name == 'schedule' ||
(github.event_name == 'pull_request' && github.event.pull_request.draft == false)
)
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all # Ensure we have id-token:write access for vault-auth.
needs:
- setup
@ -558,6 +589,39 @@ jobs:
- id: slackbot-webhook-url
run:
echo "slackbot-webhook-url=${{ needs.setup.outputs.is-ent-repo != 'true' && secrets.FEED_VAULT_CI_OFFICIAL_WEBHOOK_URL || steps.secrets.outputs.slackbot-webhook-url }}" >> "$GITHUB_OUTPUT"
- if: ${{ needs.setup.outputs.is-fork == 'false' }}
name: Download failure summaries
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: failure-summary-*.md
path: failure-summaries
merge-multiple: true
- if: ${{ needs.setup.outputs.is-fork == 'false' }}
id: prepare-failure-summary
name: Prepare failure summary
run: |
# Sort all of the summary table rows and push them to a temp file.
temp_file_name=temp-$(date +%s)
find failure-summaries -name '*.md' -type f -exec cat {} \; 2>/dev/null | sort >> "$temp_file_name" || true
# If there are test failures, present them in a format of a GitHub Markdown table.
if [ -s "$temp_file_name" ]; then
# Here we create the headings for the summary table
{
echo "| Test Type | Package | Test | Elapsed | Runner Index | Logs |"
echo "| --------- | ------- | ---- | ------- | ------------ | ---- |"
cat "$temp_file_name"
} >> "$GITHUB_STEP_SUMMARY"
else
if [ "${{ steps.status.outputs.result }}" == 'success' ]; then
echo "### All required tests passed! :white_check_mark:" >> "$GITHUB_STEP_SUMMARY"
fi
fi
{
echo 'table-test-results<<EOFTABLE'
cat "$temp_file_name"
echo EOFTABLE
} | tee -a "$GITHUB_OUTPUT"
- if: |
needs.setup.outputs.workflow-trigger == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name &&
@ -573,12 +637,26 @@ jobs:
TEST_CONTAINERS: ${{ needs.test-containers.result }}
UI: ${{ needs.ui.result }}
run: ./.github/scripts/report-build-status.sh
- name: Create test results comment
if: |
needs.setup.outputs.workflow-trigger == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name &&
(github.repository == 'hashicorp/vault' || github.repository == 'hashicorp/vault-enterprise') &&
needs.setup.outputs.is-fork == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
RUN_ID: ${{ github.run_id }}
REPO: ${{ github.event.repository.name }}
RESULT: ${{ steps.status.outputs.result }}
TABLE_DATA: ${{ steps.prepare-failure-summary.outputs.table-test-results }}
run: ./.github/scripts/report-ci-status.sh
- name: Notify build failures in Slack
if: |
always() &&
steps.status.outputs.result != 'success' &&
(github.ref_name == 'main' || startsWith(github.ref_name, 'release/'))
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
with:
errors: true # exit with an error if the payload is invalid
retries: rapid # retry if we're being rated limited
@ -617,7 +695,7 @@ jobs:
with:
version: ${{ needs.setup.outputs.vault-version-metadata }}
product: ${{ needs.setup.outputs.vault-binary-name }}
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: steps.generate-metadata-file.outcome == 'success' # upload our metadata if we created it
with:
name: metadata.json

View file

@ -15,7 +15,7 @@ jobs:
changelog-check:
# If there a `pr/no-changelog` label we ignore this check
if: "!contains(github.event.pull_request.labels.*.name, 'pr/no-changelog')"
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:

View file

@ -23,11 +23,12 @@ concurrency:
jobs:
setup:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all # vault-auth
outputs:
changed-files: ${{ steps.changed-files.outputs.changed-files }}
checkout-ref: ${{ steps.checkout.outputs.ref }}
compute-build: ${{ steps.metadata.outputs.compute-build }}
compute-small: ${{ steps.metadata.outputs.compute-small }}
compute-test-go: ${{ steps.metadata.outputs.compute-test-go }}
compute-test-ui: ${{ steps.metadata.outputs.compute-test-ui }}
@ -38,6 +39,7 @@ jobs:
is-fork: ${{ steps.metadata.outputs.is-fork }}
labels: ${{ steps.metadata.outputs.labels }}
workflow-trigger: ${{ steps.metadata.outputs.workflow-trigger }}
run-ui-tests: ${{ steps.ui-should-run.outputs.run-ui-tests }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Make sure we check out correct ref based on PR labels and such
@ -78,6 +80,12 @@ jobs:
# Don't download them on a cache hit during setup, just make sure they're cached before
# subsequent workflows are run.
no-restore: true
# Run the UI tests if our UI has changed, or a 'ui' label is present, or our workflow trigger
# was triggered by a merge to main or releases/*.
- id: ui-should-run
name: Determine whether or not we should run UI tests
run: |
echo "run-ui-tests=${{ contains(fromJSON(steps.changed-files.outputs.changed-files).groups, 'ui') || steps.metadata.outputs.workflow-trigger == 'push' || contains(steps.metadata.outputs.labels, 'ui') }}" | tee -a "$GITHUB_OUTPUT"
test-autopilot-upgrade:
name: Run Autopilot upgrade tool
@ -252,120 +260,16 @@ jobs:
test-ui:
name: Test UI
# Run the UI tests if our UI has changed, or a 'ui' label is present, or our workflow trigger
# was triggered by a merge to main or releases/*.
if: |
contains(fromJSON(needs.setup.outputs.changed-files).groups, 'ui') ||
needs.setup.outputs.workflow-trigger == 'push' ||
contains(needs.setup.outputs.labels, 'ui')
needs: setup
permissions:
id-token: write
contents: read
runs-on: ${{ fromJSON(needs.setup.outputs.compute-test-ui) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: status
with:
ref: ${{ needs.setup.outputs.checkout-ref }}
- uses: ./.github/actions/set-up-go
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Install PNPM
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
with:
run_install: false
package_json_file: './ui/package.json'
# Setup node.js with caching using the pnpm-lock.yaml file
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: './ui/package.json'
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- uses: browser-actions/setup-chrome@b94431e051d1c52dcbe9a7092a4f10f827795416 # v2.1.0
- name: ui-dependencies
working-directory: ./ui
run: |
pnpm i
npm rebuild node-sass
- if: needs.setup.outputs.is-ent-repo != 'true'
name: Rebuild font cache on Github hosted runner
# Fix `Fontconfig error: No writable cache directories` error on Github hosted runners
# This seems to have been introduced with this runner image: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20240818.1
# Hopefully this will resolve itself at some point with a newer image and we can remove it
run: fc-cache -f -v
- if: needs.setup.outputs.is-ent-repo == 'true'
id: vault-auth
name: Authenticate to Vault
run: vault-auth
- if: needs.setup.outputs.is-ent-repo == 'true'
id: secrets
name: Fetch secrets
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
with:
url: ${{ steps.vault-auth.outputs.addr }}
caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }}
token: ${{ steps.vault-auth.outputs.token }}
secrets: |
kv/data/github/hashicorp/vault-enterprise/github-token username-and-token | PRIVATE_REPO_GITHUB_TOKEN;
kv/data/github/hashicorp/vault-enterprise/license license_1 | VAULT_LICENSE;
kv/data/github/${{ github.repository }}/datadog-ci DATADOG_API_KEY;
- if: needs.setup.outputs.is-ent-repo == 'true'
name: Set up Git
run: git config --global url."https://${{ steps.secrets.outputs.PRIVATE_REPO_GITHUB_TOKEN }}@github.com".insteadOf https://github.com
- uses: ./.github/actions/install-tools
- name: build-go-dev
run: |
rm -rf ./pkg
mkdir ./pkg
make prep dev
- name: test-ui
env:
VAULT_LICENSE: ${{ steps.secrets.outputs.VAULT_LICENSE }}
run: |
export PATH="${PWD}/bin:${PATH}"
# Run Ember tests
cd ui
mkdir -p test-results/qunit
pnpm ${{ needs.setup.outputs.is-ent-branch == 'true' && 'test' || 'test:oss' }}
- if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: test-results-ui
path: ui/test-results
- name: Prepare datadog-ci
if: (github.repository == 'hashicorp/vault' || github.repository == 'hashicorp/vault-enterprise') && (success() || failure())
continue-on-error: true
run: |
if type datadog-ci > /dev/null 2>&1; then
exit 0
fi
# Curl does not always exit 1 if things go wrong. To determine if this is successful
# we'll silence all non-error output and check the results to determine success.
if ! out="$(curl -sSL --fail https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64 --output /usr/local/bin/datadog-ci 2>&1)"; then
printf "failed to download datadog-ci: %s" "$out"
fi
if [[ -n "$out" ]]; then
printf "failed to download datadog-ci: %s" "$out"
fi
chmod +x /usr/local/bin/datadog-ci
- name: Upload test results to DataDog
if: success() || failure()
continue-on-error: true
env:
DD_ENV: ci
run: |
if [[ ${{ github.repository }} == 'hashicorp/vault' ]]; then
export DATADOG_API_KEY=${{ secrets.DATADOG_API_KEY }}
fi
datadog-ci junit upload --service "$GITHUB_REPOSITORY" 'ui/test-results/qunit/results.xml'
- if: always()
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
with:
paths: "ui/test-results/qunit/results.xml"
show: "fail"
if: needs.setup.outputs.run-ui-tests == 'true'
uses: ./.github/workflows/test-ui.yml
with:
checkout-ref: ${{ needs.setup.outputs.checkout-ref }}
runs-on: ${{ needs.setup.outputs.compute-build }}
runs-on-small: ${{ needs.setup.outputs.compute-test-ui }}
is-ent-repo: ${{ needs.setup.outputs.is-ent-repo }}
is-ent-branch: ${{ needs.setup.outputs.is-ent-branch }}
secrets: inherit
tests-completed:
needs:
@ -377,7 +281,7 @@ jobs:
- test-go-fips
- test-ui
if: always()
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all # Ensure we have id-token:write access for vault-auth.
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@ -430,8 +334,7 @@ jobs:
secrets: |
kv/data/github/${{ github.repository }}/slack feed-vault-ci-official-webhook-url | slackbot-webhook-url;
- id: slackbot-webhook-url
run:
echo "slackbot-webhook-url=${{ needs.setup.outputs.is-ent-repo != 'true' && secrets.FEED_VAULT_CI_OFFICIAL_WEBHOOK_URL || steps.secrets.outputs.slackbot-webhook-url }}" >> "$GITHUB_OUTPUT"
run: echo "slackbot-webhook-url=${{ needs.setup.outputs.is-ent-repo != 'true' && secrets.FEED_VAULT_CI_OFFICIAL_WEBHOOK_URL || steps.secrets.outputs.slackbot-webhook-url }}" >> "$GITHUB_OUTPUT"
- if: |
always() &&
needs.setup.outputs.workflow-trigger == 'push' &&
@ -445,7 +348,7 @@ jobs:
needs.test-ui.result == 'failure'
)
name: Notify build failures in Slack
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
with:
errors: true # exit with an error if the payload is invalid
retries: rapid # retry if we're being rated limited
@ -486,13 +389,16 @@ jobs:
# Only create the PR summary if it's a pull request and it is not a fork as we need access
# to secrets.
- if: ${{ needs.setup.outputs.is-fork == 'false' }}
id: download-summaries
name: Download failure summaries
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: failure-summary-*.md
path: failure-summaries
merge-multiple: true
- if: ${{ needs.setup.outputs.is-fork == 'false' }}
# Don't allow failure summary aggregation to fail this workflow
continue-on-error: true
- if: needs.setup.outputs.is-fork == 'false' && steps.download-summaries.outcome == 'success'
id: prepare-failure-summary
name: Prepare failure summary
run: |
@ -507,10 +413,10 @@ jobs:
echo "| Test Type | Package | Test | Elapsed | Runner Index | Logs |"
echo "| --------- | ------- | ---- | ------- | ------------ | ---- |"
cat "$temp_file_name"
} >> "$GITHUB_STEP_SUMMARY"
} | tee -a "$GITHUB_STEP_SUMMARY"
else
if [ "${{ steps.status.outputs.result }}" == 'success' ]; then
echo "### All required Go tests passed! :white_check_mark:" >> "$GITHUB_STEP_SUMMARY"
echo "### All required Go tests passed! :white_check_mark:" | tee -a "$GITHUB_STEP_SUMMARY"
fi
fi
{
@ -519,7 +425,7 @@ jobs:
echo EOFTABLE
} | tee -a "$GITHUB_OUTPUT"
- name: Create comment
if: github.head_ref != '' && needs.setup.outputs.is-fork == 'false'
if: github.head_ref != '' && needs.setup.outputs.is-fork == 'false' && steps.prepare-failure-summary.outcome == 'success'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}

View file

@ -15,7 +15,7 @@ concurrency:
jobs:
setup:
name: Setup
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Ensure Go modules are cached
@ -30,7 +30,7 @@ jobs:
deprecations:
name: Deprecated functions
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
needs: setup
if: github.base_ref == 'main'
steps:
@ -47,7 +47,7 @@ jobs:
codechecker:
name: Code checks
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
needs: setup
if: github.base_ref == 'main'
steps:
@ -69,7 +69,7 @@ jobs:
generate-delta:
name: Protobuf generate delta
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
needs: setup
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@ -83,7 +83,7 @@ jobs:
format:
name: Format
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
needs: setup
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@ -101,7 +101,7 @@ jobs:
semgrep:
name: Semgrep
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
container:
image: returntocorp/semgrep@sha256:cfad18cfb6536aa48ad5a71017207a10320b4e17e3b2bd7b7de27b42dc9651e7 #v1.58
steps:

View file

@ -14,7 +14,7 @@ permissions:
jobs:
copywrite:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: hashicorp/setup-copywrite@32638da2d4e81d56a0764aa1547882fc4d209636 # v1.1.3

View file

@ -15,7 +15,7 @@ jobs:
do-not-merge-check:
# If there is a `do-not-merge` label we ignore this check
if: ${{ contains(github.event.pull_request.labels.*.name, 'do-not-merge') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- name: Fail if do-not-merge label is applied
run: |

View file

@ -12,7 +12,7 @@ jobs:
# as we need secrets to install enos.
if: "! github.event.pull_request.head.repo.fork"
name: metadata
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
outputs:
runs-on: ${{ steps.metadata.outputs.runs-on }}
version: ${{ steps.metadata.outputs.version }}
@ -27,7 +27,7 @@ jobs:
echo "version=${{ steps.set-product-version.outputs.product-version }}" >> "$GITHUB_OUTPUT"
github_repository="${{ github.repository }}"
if [ "${github_repository##*/}" == "vault-enterprise" ] ; then
echo 'runs-on=["self-hosted","ubuntu-latest-x64","type=c6a.2xlarge;c6a.4xlarge;c6a.8xlarge"]' >> "$GITHUB_OUTPUT"
echo 'runs-on=["self-hosted","ubuntu-22.04-x64","large"]' >> "$GITHUB_OUTPUT"
else
echo 'runs-on="custom-linux-xl-vault-latest"' >> "$GITHUB_OUTPUT"
fi
@ -42,10 +42,10 @@ jobs:
no-restore: true
no-save: true
- uses: ./.github/actions/install-tools
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
- uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
with:
terraform_wrapper: false
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
- uses: hashicorp/action-setup-enos@6ec106c8f809fe645162d73bea565c65f3269907 # v1.52
- name: Ensure shellcheck is available for linting
run: which shellcheck || (sudo apt update && sudo apt install -y shellcheck)
- name: lint

View file

@ -11,7 +11,7 @@ concurrency:
jobs:
mend-scan:
if: ${{ github.repository == 'hashicorp/vault-enterprise' }}
runs-on: [self-hosted, ubuntu-latest-x64]
runs-on: [self-hosted, ubuntu-22.04-x64]
permissions:
id-token: write
contents: read
@ -34,7 +34,7 @@ jobs:
psirt-id: "PSIRT_PRD0014264"
- name: Upload Scan Artifacts
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: always()
with:
name: mend-scan-results-pr-${{ github.event.number }}

View file

@ -20,7 +20,7 @@ jobs:
if: ${{ ((github.repository == 'hashicorp/vault' || github.repository == 'hashicorp/vault-enterprise')
&& (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name))
&& (!contains(github.event.pull_request.labels.*.name, 'pr/no-milestone')) }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- name: Check milestone
run: ${{ github.event.pull_request.milestone != null }}

View file

@ -21,7 +21,7 @@ jobs:
- if: github.event.pull_request != null
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- if: github.event.pull_request != null
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: changes
with:
# derived from CODEOWNERS

View file

@ -15,7 +15,7 @@ on:
jobs:
plugin-update-check:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
env:
PLUGIN_REPO: "${{inputs.repo}}"
PLUGIN_BRANCH: "${{inputs.plugin_branch}}"
@ -29,7 +29,7 @@ jobs:
# https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow
token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
cache: false # save cache space for vault builds: https://github.com/hashicorp/vault/pull/21764
go-version-file: .go-version

View file

@ -31,7 +31,7 @@ on:
jobs:
plugin-update:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
env:
GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
GOPRIVATE: github.com/hashicorp/*

View file

@ -10,7 +10,7 @@ jobs:
RemoveWaitingLabelFromClosedIssueOrPR:
if: github.event.action == 'closed'
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- name: Remove triaging labels from closed issues and PRs
uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0

View file

@ -16,7 +16,7 @@ on:
jobs:
scan:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ondemand","os=linux","type=c6a.4xlarge;c6a.2xlarge;m8a.4xlarge;c6a.8xlarge"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64","xlarge"]') }}
# The first check ensures this doesn't run on community-contributed PRs, who won't have the
# permissions to run this job.
if: |
@ -27,7 +27,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
cache: false # save cache space for vault builds: https://github.com/hashicorp/vault/pull/21764
go-version: 'stable'

View file

@ -22,7 +22,7 @@ on:
jobs:
bootstrap-ci:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all
env:
TF_WORKSPACE: "${{ github.event.repository.name }}-ci-enos-bootstrap"
@ -32,11 +32,11 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
with:
terraform_wrapper: false
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}

View file

@ -7,14 +7,14 @@ on:
jobs:
setup:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all
outputs:
regions: ${{steps.setup.outputs.regions}}
steps:
- name: Configure AWS credentials
id: aws-configure
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}
@ -29,7 +29,7 @@ jobs:
aws-nuke:
needs: setup
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
container:
image: ghcr.io/ekristen/aws-nuke:v3.51.0 # https://github.com/ekristen/aws-nuke/pkgs/container/aws-nuke
options:
@ -43,7 +43,7 @@ jobs:
steps:
- name: Configure AWS credentials
id: aws-configure
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}
@ -68,7 +68,7 @@ jobs:
check-quotas:
needs: [ setup, aws-nuke ]
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
container:
image: jantman/awslimitchecker
env:
@ -80,7 +80,7 @@ jobs:
steps:
- name: Configure AWS credentials
id: aws-configure
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}

View file

@ -35,7 +35,7 @@ on:
jobs:
get-metadata:
name: Get metadata
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
outputs:
is-ent-branch: ${{ steps.metadata.outputs.is-ent-branch }}
is-ent-repo: ${{ steps.metadata.outputs.is-ent-repo }}
@ -48,7 +48,7 @@ jobs:
- id: get-outputs
run: |
if [[ '${{ steps.metadata.outputs.is-ent-repo }}' == 'true' ]]; then
echo "runs-on=['self-hosted', 'ondemand', 'os=linux', 'type=m8a.4xlarge;m7a.4xlarge;m5d.4xlarge']" >> "$GITHUB_OUTPUT"
echo 'runs-on=["self-hosted","ubuntu-22.04-x64","xlarge"]' >> "$GITHUB_OUTPUT"
else
echo "runs-on=\"custom-linux-xl-vault-latest\"" >> "$GITHUB_OUTPUT"
fi
@ -82,23 +82,23 @@ jobs:
- uses: ./.github/actions/set-up-go
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
- uses: hashicorp/action-setup-enos@6ec106c8f809fe645162d73bea565c65f3269907 # v1.52
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Set Up Git
run: git config --global url."https://${{ secrets.elevated_github_token }}:@github.com".insteadOf "https://github.com"
- name: Set Up Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: './ui/package.json'
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- name: Install PNPM
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
package_json_file: './ui/package.json'
- name: Set Up Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
with:
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
terraform_wrapper: false
@ -120,12 +120,12 @@ jobs:
sudo apt install -y libnss3-dev libgdk-pixbuf2.0-dev libgtk-3-dev libxss-dev libasound2
- name: Install Chrome
if: steps.chrome-check.outputs.chrome-version == 'not-installed'
uses: browser-actions/setup-chrome@b94431e051d1c52dcbe9a7092a4f10f827795416 # v2.1.0
uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1
- name: Installed Chrome Version
run: |
echo "Installed Chrome Version = [$(chrome --version 2> /dev/null || google-chrome --version 2> /dev/null || google-chrome-stable --version 2> /dev/null)]"
- name: Configure AWS credentials from Test account
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}

View file

@ -147,7 +147,7 @@ jobs:
- uses: ./.github/actions/install-tools # for gotestsum
- run: mkdir -p ${{ steps.local-metadata.outputs.go-test-dir }}
- if: inputs.test-timing-cache-restore || inputs.test-timing-cache-save
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ steps.local-metadata.outputs.go-test-dir }}
key: ${{ inputs.test-timing-cache-key }}-${{ github.run_number }}
@ -185,7 +185,7 @@ jobs:
# testonly tagged tests need an additional tag to be included
# also running some extra tests for sanity checking with the testonly build tag
(
go list -tags=testonly ./vault/external_tests/{kv,token,*replication-perf*,*testonly*} ./command/*testonly* ./vault/ | gotestsum tool ci-matrix --debug \
go list -tags=testonly ./vault/external_tests/{kv,token,*replication-perf*,*testonly*,*verify*} ./command/*testonly* ./vault/ | gotestsum tool ci-matrix --debug \
--partitions "${{ inputs.total-runners }}" \
--timing-files '${{ steps.local-metadata.outputs.go-test-dir }}/*.json' > matrix.json
)
@ -338,7 +338,33 @@ jobs:
# The dev mode binary has to exist for binary tests that are dispatched on the last runner.
env:
GOPRIVATE: github.com/hashicorp/*
run: time make prep dev
run: |
set -exo pipefail
time make prep dev
mv bin/vault vault-binary
- if: inputs.binary-tests && matrix.id == inputs.total-runners
id: build-docker-image
name: Build Docker image with custom vault binary
run: |
set -exo pipefail
if [ "${{ needs.test-matrix.outputs.is-ent-branch }}" == "true" ]; then
go run ./tools/testimagemaker/ -source=docker.io/hashicorp/vault-enterprise:latest -target=hashicorp/vault-enterprise-ci:latest -binary=./vault-binary
go run ./tools/testimagemaker/ -source=docker.io/hashicorp/vault-enterprise:2.0.1-ent.hsm -target=hashicorp/vault-enterprise-ci:latest-hsm -binary=./vault-hsm-binary -hsm
# Verify the images were built successfully
docker images hashicorp/vault-enterprise-ci:latest
echo "image=hashicorp/vault-enterprise-ci:latest" >> "$GITHUB_OUTPUT"
docker images hashicorp/vault-enterprise-ci:latest-hsm
echo "hsmimage=hashicorp/vault-enterprise-ci:latest-hsm" >> "$GITHUB_OUTPUT"
else
go run ./tools/testimagemaker/ -source=docker.io/hashicorp/vault:latest -target=hashicorp/vault-ci:latest -binary=./vault-binary
# Verify the images was built successfully
docker images hashicorp/vault-ci:latest
echo "image=hashicorp/vault-ci:latest" >> "$GITHUB_OUTPUT"
fi
- if: needs.test-matrix.outputs.is-ent-repo != 'true'
# Enterprise repo runners do not allow sudo, so can't install gVisor there yet.
name: Install gVisor
@ -402,17 +428,26 @@ jobs:
# The docker/binary tests are more expensive, and we've had problems with timeouts when running at full
# parallelism. The default if -p isn't specified is to use NumCPUs, which seems fine for regular tests.
package_parallelism=""
test_parallelism="${{ inputs.go-test-parallelism }}"
if [ -f vault-hsm-binary ]; then
VAULT_HSM_BINARY="$(pwd)/vault-hsm-binary"
export VAULT_HSM_BINARY
# The image will be preferred by most docker tests, since it doesn't require the extra
# overhead of mutating an image to add the current binary. We still populate $VAULT_BINARY
# for the sake of exec tests like TestSysPprof_Exec.
if [ -f vault-binary ]; then
VAULT_BINARY=$(pwd)/vault-binary
export VAULT_BINARY
export VAULT_IMAGE=${{ steps.build-docker-image.outputs.image }}
fi
if [ -f bin/vault ]; then
VAULT_BINARY="$(pwd)/bin/vault"
export VAULT_BINARY
if [ -f vault-hsm-binary ]; then
VAULT_HSM_BINARY=$(pwd)/vault-hsm-binary
export VAULT_HSM_BINARY
export VAULT_HSM_IMAGE=${{ steps.build-docker-image.outputs.hsmimage }}
fi
if [ -f vault-binary ] || [ -f vault-hsm-binary ]; then
package_parallelism="-p 2"
test_parallelism=4
fi
# If running Go tests on the enterprise repo, add a flag to rerun failed tests.
@ -436,7 +471,7 @@ jobs:
$package_parallelism \
-tags "${{ inputs.go-tags }}" \
-timeout=${{ inputs.go-test-timeout }} \
-parallel=${{ inputs.go-test-parallelism }} \
-parallel="$test_parallelism" \
${{ inputs.extra-flags }} \
- if: (github.repository == 'hashicorp/vault' || github.repository == 'hashicorp/vault-enterprise') && (success() || failure())
name: Prepare datadog-ci
@ -473,14 +508,14 @@ jobs:
tar -cvf '${{ steps.metadata.outputs.go-test-log-archive-name }}' -C "${{ steps.metadata.outputs.go-test-log-dir }}" .
- if: success() || failure()
name: Upload test logs archives
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.metadata.outputs.go-test-log-archive-name }}
path: ${{ steps.metadata.outputs.go-test-log-archive-name }}
retention-days: 7
- if: success() || failure()
name: Upload test results
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.metadata.outputs.go-test-results-upload-key }}
path: |
@ -518,7 +553,7 @@ jobs:
echo "data-race-result=${result}" | tee -a "$GITHUB_OUTPUT"
- if: (success() || failure()) && steps.data-race-check.outputs.data-race-result == 'failure'
name: Upload data race detector failure log
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.metadata.outputs.data-race-log-upload-key }}
path: ${{ steps.metadata.outputs.go-test-dir }}/${{ steps.metadata.outputs.data-race-log-file }}
@ -530,7 +565,7 @@ jobs:
# so we have to fetch it from the API
- if: success() || failure()
name: Fetch job logs URL
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
continue-on-error: true
with:
retries: 3
@ -592,7 +627,7 @@ jobs:
>> '${{ steps.metadata.outputs.failure-summary-file-name }}'
- if: success() || failure()
name: Upload failure summary
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.metadata.outputs.failure-summary-file-name }}
path: ${{ steps.metadata.outputs.failure-summary-file-name }}
@ -609,7 +644,7 @@ jobs:
data-race-output: ${{ steps.status.outputs.data-race-output }}
data-race-result: ${{ steps.status.outputs.data-race-result }}
steps:
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: ${{ needs.test-go.outputs.data-race-log-download-pattern }}
path: data-race-logs
@ -651,7 +686,7 @@ jobs:
} | tee -a "$GITHUB_OUTPUT"
# Aggregate, prune, and cache our timing data
- if: ${{ ! cancelled() && needs.test-go.result == 'success' && inputs.test-timing-cache-save }}
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ${{ needs.test-matrix.outputs.go-test-dir }}
key: ${{ inputs.test-timing-cache-key }}-${{ github.run_number }}
@ -659,7 +694,7 @@ jobs:
${{ inputs.test-timing-cache-key }}-
go-test-timing-
- if: ${{ ! cancelled() && needs.test-go.result == 'success' && inputs.test-timing-cache-save }}
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ needs.test-matrix.outputs.go-test-dir }}
pattern: ${{ needs.test-go.outputs.go-test-results-download-pattern }}

View file

@ -18,14 +18,14 @@ env:
jobs:
go-test:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/set-up-go
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- run: go test -v ./${{ inputs.path }}/... 2>&1 | tee ${{ inputs.name }}.txt
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ inputs.name }}-output
path: ${{ inputs.name }}.txt

View file

@ -34,7 +34,7 @@ on:
jobs:
metadata:
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
outputs:
build-date: ${{ steps.metadata.outputs.build-date }}
is-ent-repo: ${{ steps.global-metadata.outputs.is-ent-repo }}
@ -44,7 +44,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.vault-revision }}
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
- uses: hashicorp/action-setup-enos@6ec106c8f809fe645162d73bea565c65f3269907 # v1.52
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- uses: ./.github/actions/metadata
@ -73,7 +73,7 @@ jobs:
run:
needs: metadata
name: run ${{ matrix.scenario.id.filter }}
runs-on: ${{ fromJSON(needs.metadata.outputs.is-ent-repo == 'true' && (contains(inputs.build-artifact-name, 'arm64') && '["self-hosted","ondemand","os=ubuntu-arm","type=c6g.xlarge;c6g.2xlarge;c6g.4xlarge"]' || '["self-hosted","ubuntu-latest-x64"]') || (contains(inputs.build-artifact-name, 'arm64') && '"ubuntu-22.04-arm"' || '"ubuntu-latest"')) }}
runs-on: ${{ fromJSON(needs.metadata.outputs.is-ent-repo == 'true' && (contains(inputs.build-artifact-name, 'arm64') && '["self-hosted","ubuntu-24.04-arm64"]' || '["self-hosted","ubuntu-22.04-x64"]') || (contains(inputs.build-artifact-name, 'arm64') && '"ubuntu-22.04-arm"' || '"ubuntu-latest"')) }}
strategy:
fail-fast: false # don't fail as that can skip required cleanup steps for jobs
matrix:
@ -82,17 +82,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
with:
# the Terraform wrapper will break Terraform execution in Enos because
# it changes the output to text when we expect it to be JSON.
terraform_wrapper: false
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Download Docker Image
id: download
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ inputs.build-artifact-name }}
path: ./enos/support/downloads
@ -101,40 +93,22 @@ jobs:
run: |
echo "${{ secrets.VAULT_LICENSE }}" > ./enos/support/vault.hclic || true
- name: Run Enos scenario
id: run
# Continue once and retry to handle occasional blips when creating
# infrastructure.
continue-on-error: true
id: run-scenario
env:
ENOS_VAR_terraform_plugin_cache_dir: ../support/terraform-plugin-cache
ENOS_VAR_vault_build_date: ${{ needs.metadata.outputs.build-date }}
ENOS_VAR_vault_version: ${{ needs.metadata.outputs.vault-version }}
ENOS_VAR_vault_revision: ${{ inputs.vault-revision }}
ENOS_VAR_container_image_archive: ${{steps.download.outputs.download-path}}/${{ inputs.build-artifact-name }}
run: |
mkdir -p ./enos/support/terraform-plugin-cache
enos scenario run --timeout 10m0s --chdir ./enos/k8s ${{ matrix.scenario.id.filter }}
- name: Retry Enos scenario
id: run_retry
if: steps.run.outcome == 'failure'
env:
ENOS_VAR_terraform_plugin_cache_dir: ../support/terraform-plugin-cache
ENOS_VAR_vault_build_date: ${{ needs.metadata.outputs.build-date }}
ENOS_VAR_vault_version: ${{ needs.metadata.outputs.vault-version }}
ENOS_VAR_vault_revision: ${{ inputs.vault-revision }}
ENOS_VAR_container_image_archive: ${{steps.download.outputs.download-path}}/${{ inputs.build-artifact-name }}
run: |
enos scenario run --timeout 10m0s --chdir ./enos/k8s ${{ matrix.scenario.id.filter }}
- name: Destroy Enos scenario
if: ${{ always() }}
env:
ENOS_VAR_terraform_plugin_cache_dir: ../support/terraform-plugin-cache
ENOS_VAR_vault_build_date: ${{ needs.metadata.outputs.build-date }}
ENOS_VAR_vault_version: ${{ needs.metadata.outputs.vault-version }}
ENOS_VAR_vault_revision: ${{ inputs.vault-revision }}
ENOS_VAR_container_image_archive: ${{steps.download.outputs.download-path}}/${{ inputs.build-artifact-name }}
run: |
enos scenario destroy --timeout 10m0s --grpc-listen http://localhost --chdir ./enos/k8s ${{ matrix.scenario.id.filter }}
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ matrix.scenario.id.filter }}
working-directory: ./enos/k8s
timeout: 10m0s
retry-timeout: 10m0s
destroy-timeout: 10m0s
show-state-on-retry: ${{ github.repository == 'hashicorp/vault-enterprise' && 'true' || 'false' }}
destroy-extra-args: --grpc-listen http://localhost
- name: Cleanup Enos runtime directories
if: ${{ always() }}
run: |

View file

@ -43,7 +43,7 @@ on:
jobs:
metadata:
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions:
id-token: write # vault-auth
contents: read
@ -70,7 +70,7 @@ jobs:
token: ${{ steps.vault-auth.outputs.token }}
secrets: |
kv/data/github/${{ github.repository }}/github-token token | ELEVATED_GITHUB_TOKEN;
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
- uses: hashicorp/action-setup-enos@6ec106c8f809fe645162d73bea565c65f3269907 # v1.52
with:
github-token: ${{ github.repository == 'hashicorp/vault' && secrets.ELEVATED_GITHUB_TOKEN || steps.vault-secrets.outputs.ELEVATED_GITHUB_TOKEN }}
- uses: ./.github/actions/create-dynamic-config
@ -112,6 +112,7 @@ jobs:
permissions:
id-token: write # vault-auth
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@ -138,7 +139,9 @@ jobs:
kv/data/github/${{ github.repository }}/slack feed-vault-enos-failures-webhook-url | SLACK_WEBHOOK_URL;
kv/data/github/${{ github.repository }}/enos ssh-key | SSH_KEY_PRIVATE_CI;
kv/data/github/${{ github.repository }}/license license_1 | VAULT_LICENSE;
kv/data/github/${{ github.repository }}/ibm-license license_1 | VAULT_LICENSE_IBM;
kv/data/github/${{ github.repository }}/github-token token | ELEVATED_GITHUB_TOKEN;
- id: secrets
run: |
if [[ "${{ needs.metadata.outputs.is-ent-repo }}" != 'true' ]]; then
@ -155,6 +158,7 @@ jobs:
echo "${{ secrets.SSH_KEY_PRIVATE_CI }}"
echo EOFSSHKEYCE
echo 'vault-license=${{ secrets.VAULT_LICENSE }}'
echo 'vault-license-ibm=${{ secrets.VAULT_LICENSE_IBM }}'
} | tee -a "$GITHUB_OUTPUT"
else
{
@ -170,8 +174,10 @@ jobs:
echo "${{ steps.vault-secrets.outputs.SSH_KEY_PRIVATE_CI }}"
echo EOFSSHKEYENT
echo 'vault-license=${{ steps.vault-secrets.outputs.VAULT_LICENSE }}'
echo 'vault-license-ibm=${{ steps.vault-secrets.outputs.VAULT_LICENSE_IBM }}'
} | tee -a "$GITHUB_OUTPUT"
fi
- id: env
run: |
# Configure input environment variables.
@ -191,6 +197,7 @@ jobs:
echo 'ENOS_VAR_vault_artifact_path=./support/downloads/${{ inputs.build-artifact-name }}'
echo 'ENOS_VAR_vault_build_date=${{ needs.metadata.outputs.build-date }}'
echo 'ENOS_VAR_vault_license_path=./support/vault.hclic'
echo 'ENOS_VAR_vault_ibm_license_path=./support/ibm-pao.lic'
echo 'ENOS_VAR_vault_product_version=${{ needs.metadata.outputs.vault-version }}'
echo 'ENOS_VAR_vault_radar_license_path=./support/vault-radar.hclic'
echo 'ENOS_VAR_vault_revision=${{ inputs.vault-revision }}'
@ -200,13 +207,20 @@ jobs:
echo 'ENOS_VAR_verify_ldap_secrets_engine=false'
echo 'ENOS_VAR_verify_log_secrets=true'
} | tee -a "$GITHUB_ENV"
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
- uses: ./.github/actions/set-up-go
with:
# the Terraform wrapper will break Terraform execution in Enos because
# it changes the output to text when we expect it to be JSON.
terraform_wrapper: false
github-token: ${{ steps.secrets.outputs.github-token }}
- name: Install LDAP client tools
run: |
sudo apt-get update
sudo apt-get install -y ldap-utils
- uses: ./.github/actions/install-tools
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ steps.secrets.outputs.aws-access-key-id }}
aws-secret-access-key: ${{ steps.secrets.outputs.aws-secret-access-key }}
@ -214,14 +228,13 @@ jobs:
role-to-assume: ${{ steps.secrets.outputs.aws-role-arn }}
role-skip-session-tagging: true
role-duration-seconds: 3600
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
with:
github-token: ${{ steps.secrets.outputs.github-token }}
- uses: ./.github/actions/create-dynamic-config
with:
github-token: ${{ steps.secrets.outputs.github-token }}
vault-version: ${{ inputs.vault-version }}
vault-edition: ${{ inputs.vault-edition }}
- name: Prepare scenario dependencies
id: prepare_scenario
run: |
@ -230,50 +243,136 @@ jobs:
chmod 600 "./enos/support/private_key.pem"
sha256sum "./enos/support/private_key.pem"
du -h "./enos/support/private_key.pem"
echo "debug_data_artifact_name=enos-debug-data_$(echo "${{ matrix.scenario }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')" >> "$GITHUB_OUTPUT"
{
echo "debug_data_artifact_name=enos-debug-data_$(echo "${{ matrix.scenario }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')"
echo "test_results_artifact_name=test-results_$(echo "${{ matrix.scenario.id.filter }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')"
echo "junit_results_artifact_name=junit-results_$(echo "${{ matrix.scenario.id.filter }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')"
echo "failure_summary_artifact_name=failure-summary-enos_$(echo "${{ matrix.scenario.id.filter }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g').md"
} | tee -a "$GITHUB_OUTPUT"
- if: contains(inputs.sample-name, 'build')
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ inputs.build-artifact-name }}
path: ./enos/support/downloads
- if: contains(inputs.sample-name, 'ent')
name: Configure Vault license
run: echo "${{ steps.secrets.outputs.vault-license }}" > ./enos/support/vault.hclic || true
name: Configure Vault licenses
run: |
echo "${{ steps.secrets.outputs.vault-license }}" > ./enos/support/vault.hclic || true
echo "${{ steps.secrets.outputs.vault-license-ibm }}" > ./enos/support/ibm-pao.lic || true
- if: contains(matrix.scenario.id.filter, 'consul_edition:ent')
name: Configure Consul license
run: |
echo "${{ steps.secrets.outputs.consul-license }}" > ./enos/support/consul.hclic || true
- name: Configure Vault Radar license
run: |
echo "${{ steps.secrets.outputs.radar-license }}" > ./enos/support/vault-radar.hclic || true
- id: launch
name: enos scenario launch ${{ matrix.scenario.id.filter }}
# Continue once and retry to handle occasional blips when creating infrastructure.
continue-on-error: true
run: enos scenario launch --timeout 45m0s --chdir ./enos ${{ matrix.scenario.id.filter }}
- if: steps.launch.outcome == 'failure'
id: launch_retry
name: Retry enos scenario launch ${{ matrix.scenario.id.filter }}
run: enos scenario launch --timeout 45m0s --chdir ./enos ${{ matrix.scenario.id.filter }}
- name: Upload Debug Data
if: failure()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- id: run-scenario
name: Run Enos scenario ${{ matrix.scenario.id.filter }}
uses: ./.github/actions/run-enos-scenario
with:
# The name of the artifact is the same as the matrix scenario name with the spaces replaced with underscores and colons replaced by equals.
name: ${{ steps.prepare_scenario.outputs.debug_data_artifact_name }}
path: ${{ env.ENOS_DEBUG_DATA_ROOT_DIR }}
retention-days: 30
scenario-filter: ${{ matrix.scenario.id.filter }}
working-directory: ./enos
timeout: 45m0s
retry-timeout: 30m0s
destroy-timeout: 10m0s
show-state-on-retry: ${{ github.repository == 'hashicorp/vault-enterprise' && 'true' || 'false' }}
upload-debug-data: 'true'
debug-data-retention-days: '30'
debug-data-path: ${{ env.ENOS_DEBUG_DATA_ROOT_DIR }}
- name: Upload Test Results
if: always()
id: upload_test_results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.prepare_scenario.outputs.test_results_artifact_name }}
path: /tmp/vault_test_results_*.json
retention-days: 7
if-no-files-found: ignore
continue-on-error: true
- if: ${{ always() }}
id: destroy
name: enos scenario destroy ${{ matrix.scenario.id.filter }}
- name: Upload JUnit Test Results
if: always()
id: upload_junit_results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.prepare_scenario.outputs.junit_results_artifact_name }}
path: /tmp/vault_test_results_*.xml
retention-days: 7
if-no-files-found: ignore
continue-on-error: true
run: enos scenario destroy --timeout 10m0s --chdir ./enos ${{ matrix.scenario.id.filter }}
- if: steps.destroy.outcome == 'failure'
id: destroy_retry
name: Retry enos scenario destroy ${{ matrix.scenario.id.filter }}
- name: Check for test results
if: always()
id: check_test_results
continue-on-error: true
run: enos scenario destroy --timeout 10m0s --chdir ./enos ${{ matrix.scenario.id.filter }}
run: |
if find /tmp -maxdepth 1 -name 'vault_test_results_*.json' -type f -print -quit 2>/dev/null | grep -q .; then
echo "has_results=true" >> "$GITHUB_OUTPUT"
else
echo "has_results=false" >> "$GITHUB_OUTPUT"
fi
- name: Prepare Test Results Summary
if: always() && steps.check_test_results.outputs.has_results == 'true'
continue-on-error: true
run: |
# Find the most recent JSON test results file
json_file=$(find /tmp -maxdepth 1 -name 'vault_test_results_*.json' -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -n1 | cut -d' ' -f2-)
if [ -n "$json_file" ] && [ -f "$json_file" ]; then
# Create failure summary file for aggregation in build.yml
failure_summary_file="${{ steps.prepare_scenario.outputs.failure_summary_artifact_name }}"
# Extract failed tests and format as table rows matching ci.yml format
# Format: | Test Type | Package | Test | Elapsed | Runner Index | Logs |
jq -r 'select(.Action == "fail") | select(.Test != null) | "| enos | \(.Package) | \(.Test) | \(.Elapsed // "N/A") | ${{ matrix.scenario.id.filter }} | [view test results :scroll:](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) |"' \
"$json_file" > "$failure_summary_file"
# Count total tests, passes, and failures
total_tests=$(jq -r 'select(.Action == "pass" or .Action == "fail") | select(.Test != null)' "$json_file" | jq -s 'length')
passed_tests=$(jq -r 'select(.Action == "pass") | select(.Test != null)' "$json_file" | jq -s 'length')
failed_tests=$(jq -r 'select(.Action == "fail") | select(.Test != null)' "$json_file" | jq -s 'length')
# Create step summary for this specific scenario
{
echo "## Test Results for ${{ matrix.scenario.id.filter }}"
echo ""
echo "- **Total Tests:** $total_tests"
echo "- **Passed:** ✅ $passed_tests"
echo "- **Failed:** ❌ $failed_tests"
echo ""
# If there are failures, create a table with details
if [ "$failed_tests" -gt 0 ]; then
echo "### Failed Tests"
echo ""
echo "| Test Type | Package | Test | Elapsed | Runner Index | Logs |"
echo "| --------- | ------- | ---- | ------- | ------------ | ---- |"
cat "${failure_summary_file}"
echo ""
fi
echo "📊 Full test results available in artifacts: \`${{ steps.prepare_scenario.outputs.test_results_artifact_name }}\`"
} >> "$GITHUB_STEP_SUMMARY"
else
echo "⚠️ No test results found in /tmp/vault_test_results_*.json" >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload Failure Summary
if: always() && steps.check_test_results.outputs.has_results == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.prepare_scenario.outputs.failure_summary_artifact_name }}
path: ${{ steps.prepare_scenario.outputs.failure_summary_artifact_name }}
if-no-files-found: ignore
continue-on-error: true
- name: Clean up Enos runtime directories
id: cleanup
if: ${{ always() }}
@ -282,34 +381,39 @@ jobs:
rm -rf /tmp/enos*
rm -rf ./enos/support
rm -rf ./enos/.enos
# Send slack notifications to #feed-vault-enos-failures any of our enos scenario commands fail.
# There is an incoming webhook set up on the "Enos Vault Failure Bot" Slackbot:
# https://api.slack.com/apps/A05E31CH1LG/incoming-webhooks
- if: ${{ always() && ! cancelled() }}
name: Notify launch failed
uses: hashicorp/actions-slack-status@1a3f63b30bd476aee1f3bd6f9d8f2aacc4f14d81 # v2.0.1
with:
failure-message: "enos scenario launch ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`"
status: ${{ steps.launch.outcome }}
status: ${{ steps.run-scenario.outputs.launch-outcome == 'failure' && 'failure' || 'success' }}
slack-webhook-url: ${{ steps.secrets.outputs.slack-webhook-url }}
- if: ${{ always() && ! cancelled() }}
name: Notify retry launch failed
uses: hashicorp/actions-slack-status@1a3f63b30bd476aee1f3bd6f9d8f2aacc4f14d81 # v2.0.1
with:
failure-message: "retry enos scenario launch ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`"
status: ${{ steps.launch_retry.outcome }}
status: ${{ steps.run-scenario.outputs.launch-retry-attempted == 'true' && steps.run-scenario.outputs.launch-outcome == 'failure' && 'failure' || 'success' }}
slack-webhook-url: ${{ steps.secrets.outputs.slack-webhook-url }}
- if: ${{ always() && ! cancelled() }}
name: Notify destroy failed
uses: hashicorp/actions-slack-status@1a3f63b30bd476aee1f3bd6f9d8f2aacc4f14d81 # v2.0.1
with:
failure-message: "enos scenario destroy ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`"
status: ${{ steps.destroy.outcome }}
status: ${{ steps.run-scenario.outputs.destroy-outcome == 'failure' && 'failure' || 'success' }}
slack-webhook-url: ${{ steps.secrets.outputs.slack-webhook-url }}
- if: ${{ always() && ! cancelled() }}
name: Notify retry destroy failed
uses: hashicorp/actions-slack-status@1a3f63b30bd476aee1f3bd6f9d8f2aacc4f14d81 # v2.0.1
with:
failure-message: "retry enos scenario destroy ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`"
status: ${{ steps.destroy_retry.outcome }}
status: ${{ steps.run-scenario.outputs.destroy-retry-attempted == 'true' && steps.run-scenario.outputs.destroy-outcome == 'failure' && 'failure' || 'success' }}
slack-webhook-url: ${{ steps.secrets.outputs.slack-webhook-url }}

View file

@ -35,7 +35,7 @@ on:
jobs:
enos-run-vault-interactive-test:
name: Enos run Vault interactive test
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-latest-x64"]') }}
runs-on: ${{ github.repository == 'hashicorp/vault' && 'ubuntu-latest' || fromJSON('["self-hosted","ubuntu-22.04-x64"]') }}
permissions: write-all
timeout-minutes: 120
env:
@ -64,26 +64,23 @@ jobs:
- uses: ./.github/actions/set-up-go
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
# Install additional tools like gotestsum that are required for Enos scenarios
- uses: ./.github/actions/install-tools
- name: Configure Git
run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com"
- name: Set up node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: './ui/package.json'
cache: pnpm
cache-dependency-path: ui/pnpm-lock.yaml
- name: Install PNPM
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
package_json_file: './ui/package.json'
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
with:
# the Terraform wrapper will break Terraform execution in Enos because
# it changes the output to text when we expect it to be JSON.
terraform_wrapper: false
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI_09042025 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI_09042025 }}
@ -91,9 +88,6 @@ jobs:
role-to-assume: ${{ secrets.AWS_ROLE_ARN_CI }}
role-skip-session-tagging: true
role-duration-seconds: 3600
- uses: hashicorp/action-setup-enos@17b90fcf9591275b468a94aefb9dc6a93017de8a # v1.50
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- name: Prepare scenario dependencies
id: scenario-deps
run: |
@ -106,29 +100,30 @@ jobs:
id: license
run: echo "${{ secrets.VAULT_LICENSE }}" > ./enos/support/vault.hclic
- name: Run Enos scenario
id: run
run: enos scenario run --timeout 60m0s --chdir ./enos ${{ inputs.scenario }}
id: run-scenario
uses: ./.github/actions/run-enos-scenario
with:
scenario-filter: ${{ inputs.scenario }}
working-directory: ./enos
timeout: 60m0s
retry-timeout: 60m0s
destroy-timeout: 60m0s
show-state-on-retry: ${{ github.repository == 'hashicorp/vault-enterprise' && 'true' || 'false' }}
destroy-extra-args: --grpc-listen http://localhost
debug-data-path: ${{ env.ENOS_DEBUG_DATA_ROOT_DIR }}
debug-data-retention-days: '1'
- name: Collect logs when scenario fails
id: collect_logs
if: ${{ always() }}
run: |
bash -x ./scripts/gha_enos_logs.sh "${{ steps.scenario-deps.outputs.logsdir }}" "${{ inputs.scenario }}" "${{ inputs.distro }}" "${{ inputs.artifact-type }}" 2>/dev/null
find "${{ steps.scenario-deps.outputs.logsdir }}" -maxdepth 0 -empty -exec rmdir {} \;
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: ${{ always() }}
with:
name: enos-scenario-logs
path: ${{ steps.scenario-deps.outputs.logsdir }}
retention-days: 1
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ always() }}
with:
name: enos-debug-data-logs
path: ${{ env.ENOS_DEBUG_DATA_ROOT_DIR }}
retention-days: 1
- name: Ensure scenario has been destroyed
if: ${{ always() }}
run: enos scenario destroy --timeout 60m0s --grpc-listen http://localhost --chdir ./enos ${{ inputs.scenario }}
- name: Clean up Enos runtime directories
if: ${{ always() }}
run: |

230
.github/workflows/test-ui.yml vendored Normal file
View file

@ -0,0 +1,230 @@
on:
workflow_call:
inputs:
checkout-ref:
description: The ref to use for checkout.
required: false
default: ${{ github.ref }}
type: string
runs-on:
description: An expression indicating which kind of runners to use Go testing jobs.
required: false
type: string
default: '"ubuntu-latest"'
runs-on-small:
description: An expression indicating which kind of runners to use for small computing jobs.
required: false
type: string
default: '"ubuntu-latest"'
is-ent-repo:
description: A boolean indicating whether the repository is an enterprise repository.
required: false
type: string
default: 'false'
is-ent-branch:
description: A boolean indicating whether the repository is an enterprise branch.
required: false
type: string
default: 'false'
jobs:
test-ui-build-go:
name: Build Vault Binary for UI Tests
permissions:
id-token: write
contents: read
runs-on: ${{ fromJSON(inputs.runs-on) }}
outputs:
ui-go-binary-artifact-id: ${{ steps.upload.outputs.artifact-id }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: status
with:
ref: ${{ inputs.checkout-ref }}
- uses: ./.github/actions/set-up-go
with:
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
- if: inputs.is-ent-repo == 'true'
id: vault-auth
name: Authenticate to Vault
run: vault-auth
- if: inputs.is-ent-repo == 'true'
id: secrets
name: Fetch secrets
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
with:
url: ${{ steps.vault-auth.outputs.addr }}
caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }}
token: ${{ steps.vault-auth.outputs.token }}
secrets: |
kv/data/github/hashicorp/vault-enterprise/github-token username-and-token | PRIVATE_REPO_GITHUB_TOKEN;
- if: inputs.is-ent-repo == 'true'
name: Set up Git
run: git config --global url."https://${{ steps.secrets.outputs.PRIVATE_REPO_GITHUB_TOKEN }}@github.com".insteadOf https://github.com
- uses: ./.github/actions/install-tools
- name: build-go-dev
run: |
rm -rf ./pkg
mkdir ./pkg
make prep dev
- name: Upload Vault Binary for UI Tests
id: upload
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
path: ./bin/vault
name: vault-ui-test-binary
retention-days: 1
test-ui-build-js:
name: Build JS for UI Tests
permissions:
id-token: write
contents: read
runs-on: ${{ fromJSON(inputs.runs-on-small) }}
outputs:
ui-js-bundle-artifact-id: ${{ steps.upload.outputs.artifact-id }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: status
with:
ref: ${{ inputs.checkout-ref }}
- name: Setup pnpm
uses: ./.github/actions/setup-pnpm
- name: Build Ember Test Bundle
working-directory: ./ui
run: pnpm build:jsondiffpatch && pnpm exec ember build --environment=test --output-path=dist
- name: Upload Ember Test Bundle
id: upload
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
path: ./ui/dist
name: vault-ui-test-bundle
retention-days: 1
test-ui:
name: Run UI Tests
needs: [test-ui-build-go, test-ui-build-js]
permissions:
id-token: write
contents: read
runs-on: ${{ fromJSON(inputs.runs-on-small) }}
strategy:
fail-fast: false
matrix:
ci-index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: status
with:
ref: ${{ inputs.checkout-ref }}
- if: inputs.is-ent-repo == 'true'
id: vault-auth
name: Authenticate to Vault
run: vault-auth
- if: inputs.is-ent-repo == 'true'
id: secrets
name: Fetch secrets
uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0
with:
url: ${{ steps.vault-auth.outputs.addr }}
caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }}
token: ${{ steps.vault-auth.outputs.token }}
secrets: |
kv/data/github/hashicorp/vault-enterprise/github-token username-and-token | PRIVATE_REPO_GITHUB_TOKEN;
kv/data/github/hashicorp/vault-enterprise/license license_1 | VAULT_LICENSE;
kv/data/github/${{ github.repository }}/datadog-ci DATADOG_API_KEY;
- name: Install Chrome
uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1
with:
chrome-version: stable
- name: Setup pnpm
uses: ./.github/actions/setup-pnpm
- name: Download Ember Test Bundle
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ./ui/dist
artifact-ids: ${{ needs.test-ui-build-js.outputs.ui-js-bundle-artifact-id }}
- name: Download Vault Binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ./bin
artifact-ids: ${{ needs.test-ui-build-go.outputs.ui-go-binary-artifact-id }}
- name: Make Vault Binary Executable
run: chmod +x ./bin/vault
- name: Set Parallel Count
# hardcoding this to 1 for now because multiple parallelism in UI tests with a vault server casuses test failures due to the shared backend
run: echo "PARALLEL_COUNT=1" >> "$GITHUB_ENV"
- name: Create test-results directory
run: mkdir -p ui/test-results/qunit
- name: Run UI Lint Checks
if: strategy.job-index == 0
working-directory: ./ui
run: pnpm lint
- name: Run UI Tests
if: strategy.job-index != 0
env:
VAULT_LICENSE: ${{ steps.secrets.outputs.VAULT_LICENSE }}
working-directory: ./ui
# NOTE: We subtract 1 from the total number of jobs because job-index 0 is the lint job
run: |
pnpm test${{ inputs.is-ent-branch == 'false' && ':oss' || '' }} \
--load-balance \
--split=$((${{ strategy.job-total }} - 1)) \
--partition=${{ strategy.job-index }} \
--parallel="$PARALLEL_COUNT" \
--path=dist
- if: always() && strategy.job-index != 0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: test-results-ui-${{ strategy.job-index }}
path: ui/test-results
- name: Prepare datadog-ci
if: always() && startsWith(github.repository, 'hashicorp/vault') && strategy.job-index != 0
continue-on-error: true
run: |
if type datadog-ci > /dev/null 2>&1; then
exit 0
fi
# Curl does not always exit 1 if things go wrong. To determine if this is successful
# we'll silence all non-error output and check the results to determine success.
if ! out="$(curl -sSL --fail https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64 --output /usr/local/bin/datadog-ci 2>&1)"; then
printf "failed to download datadog-ci: %s" "$out"
fi
if [[ -n "$out" ]]; then
printf "failed to download datadog-ci: %s" "$out"
fi
chmod +x /usr/local/bin/datadog-ci
- name: Upload test results to DataDog
if: (success() || failure()) && strategy.job-index != 0
continue-on-error: true
env:
DD_ENV: ci
run: |
if [[ ${{ github.repository }} == 'hashicorp/vault' ]]; then
export DATADOG_API_KEY=${{ secrets.DATADOG_API_KEY }}
fi
datadog-ci junit upload --service "$GITHUB_REPOSITORY" 'ui/test-results/qunit/results.xml'
- if: always() && strategy.job-index != 0
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
with:
paths: "ui/test-results/qunit/results.xml"
show: "fail"
test-ui-complete:
runs-on: ${{ fromJSON(inputs.runs-on-small) }}
needs: [test-ui-build-go, test-ui-build-js, test-ui]
steps:
- id: status
name: Determine status
run: |
results=$(tr -d '\n' <<< '${{ toJSON(needs.*.result) }}')
if ! grep -q -v -E '(failure|cancelled)' <<< "$results"; then
result="failed"
else
result="success"
fi
{
echo "result=${result}"
echo "results=${results}"
} | tee -a "$GITHUB_OUTPUT"

2
.gitignore vendored
View file

@ -66,6 +66,8 @@ Vagrantfile
enos-local.vars.hcl
enos/**/support
enos/**/kubeconfig
enos/modules/**/plan.yml
enos/sarif**.json
.terraform
.terraform.lock.hcl
.tfstate.*

View file

@ -1 +1 @@
1.26.0
1.26.4

View file

@ -45,6 +45,9 @@
set -eou pipefail
# We need extglob in order to parse remote_url_is_enterprise
shopt -s extglob
# fail takes two arguments. The first is the failure reasons and the second is
# an explanation. Both will be written to STDERR. The script will then exit 1.
fail() {
@ -60,7 +63,7 @@ fail() {
# that of hashicorp/vault-enterprise, otherwise it returns 1.
remote_url_is_enterprise() {
case "$1" in
git@github.com:hashicorp/vault-enterprise* | https://github.com/hashicorp/vault-enterprise*)
?(ssh://)git@github.com@(:|/)hashicorp/vault-enterprise?(.git) | https://github.com/hashicorp/vault-enterprise?(.git))
return 0
;;
*)
@ -131,7 +134,7 @@ main() {
fi
done
fail "git pre-push hook failed!" "git did not write expected commit information to STDIN! Please reach out to #team-vault-automation for help!"
fail "git pre-push hook failed!" "git did not write expected commit information to STDIN! This is likely because git could not push one-or-more refs to the remote repository. Did you change history with a rebase and need to force push? If that does not resolve the issue please reach out to #team-vault-automation for help!"
}
# Call the main function. We currently only care about the URL so we'll pass in

1
.node-version Normal file
View file

@ -0,0 +1 @@
20.20.2

1
.nvmrc Normal file
View file

@ -0,0 +1 @@
20.20.2

View file

@ -17,21 +17,21 @@ ulimit -c 0
# VAULT_REDIRECT_INTERFACE and VAULT_CLUSTER_INTERFACE environment variables. If
# VAULT_*_ADDR is also set, the resulting URI will combine the protocol and port
# number with the IP of the named interface.
get_addr () {
get_addr() {
local if_name=$1
local uri_template=$2
ip addr show dev $if_name | awk -v uri=$uri_template '/\s*inet\s/ { \
ip addr show dev "$if_name" | awk -v uri="$uri_template" '/\s*inet\s/ { \
ip=gensub(/(.+)\/.+/, "\\1", "g", $2); \
print gensub(/^(.+:\/\/).+(:.+)$/, "\\1" ip "\\2", "g", uri); \
exit}'
}
if [ -n "$VAULT_REDIRECT_INTERFACE" ]; then
export VAULT_REDIRECT_ADDR=$(get_addr $VAULT_REDIRECT_INTERFACE ${VAULT_REDIRECT_ADDR:-"http://0.0.0.0:8200"})
export VAULT_REDIRECT_ADDR=$(get_addr "$VAULT_REDIRECT_INTERFACE" "${VAULT_REDIRECT_ADDR:-"http://0.0.0.0:8200"}")
echo "Using $VAULT_REDIRECT_INTERFACE for VAULT_REDIRECT_ADDR: $VAULT_REDIRECT_ADDR"
fi
if [ -n "$VAULT_CLUSTER_INTERFACE" ]; then
export VAULT_CLUSTER_ADDR=$(get_addr $VAULT_CLUSTER_INTERFACE ${VAULT_CLUSTER_ADDR:-"https://0.0.0.0:8201"})
export VAULT_CLUSTER_ADDR=$(get_addr "$VAULT_CLUSTER_INTERFACE" "${VAULT_CLUSTER_ADDR:-"https://0.0.0.0:8201"}")
echo "Using $VAULT_CLUSTER_INTERFACE for VAULT_CLUSTER_ADDR: $VAULT_CLUSTER_ADDR"
fi
@ -69,38 +69,41 @@ elif vault --help "$1" 2>&1 | grep -q "vault $1"; then
set -- vault "$@"
fi
# If we are running Vault, make sure it executes as the proper user.
# If we are running Vault and the container user is root then execute as the vault user
if [ "$1" = 'vault' ]; then
if [ -z "$SKIP_CHOWN" ]; then
# If the config dir is bind mounted then chown it
if [ "$(stat -c %u /vault/config)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/config || echo "Could not chown /vault/config (may not have appropriate permissions)"
if [ "$(id -u)" != '0' ]; then
[ -n "$SKIP_CHOWN" ] && echo "Container is running as non-root user, ignoring SKIP_CHOWN" >&2
[ -n "$SKIP_SETCAP" ] && echo "Container is running as non-root user, ignoring SKIP_SETCAP" >&2
else
if [ -z "$SKIP_CHOWN" ]; then
# If the config dir is bind mounted then chown it
if [ "$(stat -c %u /vault/config)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/config || echo "Could not chown /vault/config (may not have appropriate permissions)"
fi
# If the logs dir is bind mounted then chown it
if [ "$(stat -c %u /vault/logs)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/logs
fi
# If the file dir is bind mounted then chown it
if [ "$(stat -c %u /vault/file)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/file
fi
fi
# If the logs dir is bind mounted then chown it
if [ "$(stat -c %u /vault/logs)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/logs
if [ -z "$SKIP_SETCAP" ]; then
# Allow mlock to avoid swapping Vault memory to disk
setcap cap_ipc_lock=+ep $(readlink -f $(which vault))
# In the case vault has been started in a container without IPC_LOCK privileges
if ! vault -version 1> /dev/null 2> /dev/null; then
>&2 echo "Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --cap-add IPC_LOCK"
setcap cap_ipc_lock=-ep $(readlink -f $(which vault))
fi
fi
# If the file dir is bind mounted then chown it
if [ "$(stat -c %u /vault/file)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/file
fi
fi
if [ -z "$SKIP_SETCAP" ]; then
# Allow mlock to avoid swapping Vault memory to disk
setcap cap_ipc_lock=+ep $(readlink -f $(which vault))
# In the case vault has been started in a container without IPC_LOCK privileges
if ! vault -version 1>/dev/null 2>/dev/null; then
>&2 echo "Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --cap-add IPC_LOCK"
setcap cap_ipc_lock=-ep $(readlink -f $(which vault))
fi
fi
if [ "$(id -u)" = '0' ]; then
set -- su-exec vault "$@"
set -- su-exec vault "$@"
fi
fi

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Copyright IBM Corp. 2016, 2025
# SPDX-License-Identifier: BUSL-1.1
@ -12,21 +12,21 @@ ulimit -c 0
# VAULT_REDIRECT_INTERFACE and VAULT_CLUSTER_INTERFACE environment variables. If
# VAULT_*_ADDR is also set, the resulting URI will combine the protocol and port
# number with the IP of the named interface.
get_addr () {
local if_name=$1
local uri_template=$2
ip addr show dev $if_name | awk -v uri=$uri_template '/\s*inet\s/ { \
get_addr() {
local if_name="$1"
local uri_template="$2"
ip addr show dev "$if_name" | awk -v uri="$uri_template" '/\s*inet\s/ { \
ip=gensub(/(.+)\/.+/, "\\1", "g", $2); \
print gensub(/^(.+:\/\/).+(:.+)$/, "\\1" ip "\\2", "g", uri); \
exit}'
}
if [ -n "$VAULT_REDIRECT_INTERFACE" ]; then
export VAULT_REDIRECT_ADDR=$(get_addr $VAULT_REDIRECT_INTERFACE ${VAULT_REDIRECT_ADDR:-"http://0.0.0.0:8200"})
export VAULT_REDIRECT_ADDR=$(get_addr "$VAULT_REDIRECT_INTERFACE" "${VAULT_REDIRECT_ADDR:-"http://0.0.0.0:8200"}")
echo "Using $VAULT_REDIRECT_INTERFACE for VAULT_REDIRECT_ADDR: $VAULT_REDIRECT_ADDR"
fi
if [ -n "$VAULT_CLUSTER_INTERFACE" ]; then
export VAULT_CLUSTER_ADDR=$(get_addr $VAULT_CLUSTER_INTERFACE ${VAULT_CLUSTER_ADDR:-"https://0.0.0.0:8201"})
export VAULT_CLUSTER_ADDR=$(get_addr "$VAULT_CLUSTER_INTERFACE" "${VAULT_CLUSTER_ADDR:-"https://0.0.0.0:8201"}")
echo "Using $VAULT_CLUSTER_INTERFACE for VAULT_CLUSTER_ADDR: $VAULT_CLUSTER_ADDR"
fi
@ -69,33 +69,38 @@ elif vault --help "$1" 2>&1 | grep -q "vault $1"; then
set -- vault "$@"
fi
# If we are running Vault, make sure it executes as the proper user.
# If we are running Vault and the container user is root then execute as the vault user
if [ "$1" = 'vault' ]; then
if [ -z "$SKIP_CHOWN" ]; then
# If the config dir is bind mounted then chown it
if [ "$(stat -c %u /vault/config)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/config || echo "Could not chown /vault/config (may not have appropriate permissions)"
if [ "$(id -u)" != '0' ]; then
[ -n "$SKIP_CHOWN" ] && echo "Container is running as non-root user, ignoring SKIP_CHOWN" >&2
[ -n "$SKIP_SETCAP" ] && echo "Container is running as non-root user, ignoring SKIP_SETCAP" >&2
else
if [ -z "$SKIP_CHOWN" ]; then
# If the config dir is bind mounted then chown it
if [ "$(stat -c %u /vault/config)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/config || echo "Could not chown /vault/config (may not have appropriate permissions)"
fi
# If the logs dir is bind mounted then chown it
if [ "$(stat -c %u /vault/logs)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/logs
fi
# If the file dir is bind mounted then chown it
if [ "$(stat -c %u /vault/file)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/file
fi
fi
# If the logs dir is bind mounted then chown it
if [ "$(stat -c %u /vault/logs)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/logs
fi
if [ -z "$SKIP_SETCAP" ]; then
# Allow mlock to avoid swapping Vault memory to disk
setcap cap_ipc_lock=+ep $(readlink -f $(which vault))
# If the file dir is bind mounted then chown it
if [ "$(stat -c %u /vault/file)" != "$(id -u vault)" ]; then
chown -R vault:vault /vault/file
fi
fi
if [ -z "$SKIP_SETCAP" ]; then
# Allow mlock to avoid swapping Vault memory to disk
setcap cap_ipc_lock=+ep $(readlink -f /bin/vault)
# In the case vault has been started in a container without IPC_LOCK privileges
if ! vault -version 1>/dev/null 2>/dev/null; then
>&2 echo "Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --cap-add IPC_LOCK"
setcap cap_ipc_lock=-ep $(readlink -f /bin/vault)
# In the case vault has been started in a container without IPC_LOCK privileges
if ! vault -version 1> /dev/null 2> /dev/null; then
echo "Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --cap-add IPC_LOCK" >&2
setcap cap_ipc_lock=-ep $(readlink -f $(which vault))
fi
fi
fi
fi
@ -106,8 +111,7 @@ fi
# we're now rerunning the entrypoint script as the Vault
# user but no longer need to run setup code for setcap
# or chowning directories (previously done on the first run).
if [[ "$(id -u)" == '0' ]]
then
if [ "$(id -u)" = '0' ]; then
export SKIP_CHOWN="true"
export SKIP_SETCAP="true"
exec su vault -p "$0" -- "$@"

View file

@ -119,6 +119,7 @@ changed_files {
# These exist on CE branches to please Github Actions.
joinpath(".github", "workflows", "build-artifacts-ent.yml"),
joinpath(".github", "workflows", "backport-automation-ent.yml"),
joinpath(".github", "workflows", "test-run-enos-scenario-cloud.yml"),
]
}
@ -127,7 +128,6 @@ changed_files {
base_dir = [
"website",
joinpath(".release", "docker"),
joinpath("enos", "modules"),
joinpath("scripts", "docker"),
]
}
@ -147,6 +147,26 @@ changed_files {
]
}
// Ignore some enos modules related to HSM
ignore {
base_dir = [
# The next matcher looks for HSM but we can ignore the softhsm modules
joinpath("enos", "modules", "softhsm_install"),
joinpath("enos", "modules", "softhsm_create_vault_keys"),
joinpath("enos", "modules", "softhsm_init"),
joinpath("enos", "modules", "softhsm_distribute_vault_keys"),
# Some filename have ent in them
joinpath("enos", "modules", "verify_secrets_engines"),
]
}
// Make sure our zap scanner is always ent only
match {
base_dir = [
joinpath("enos", "modules", "zap_scan_ent")
]
}
// Match whole directories that are enterprise only
match {
base_dir = [
@ -217,6 +237,35 @@ changed_files {
}
}
// The "hcp" group is for files that are unique to testing Vault in the
// HashiCorp Cloud Platform, i.e. HVD or Vault Cloud.
group "hcp" {
match {
file = [
joinpath(".github", "workflows", "build-hcp-image.yml"),
joinpath(".github", "workflows", "test-run-enos-scenario-cloud.yml"),
joinpath("enos", "enos-scenario-cloud-ent.hcl"),
]
}
match {
base_dir = [
joinpath("enos", "modules", "cloud_docker_vault_cluster"),
joinpath("enos", "modules", "hcp"),
joinpath("tools", "pipeline", "internal", "pkg", "hcp"),
]
}
match {
base_dir = [
joinpath("tools", "pipeline", "internal", "cmd"),
]
contains = [
"hcp"
]
}
}
// The "pipeline" group matches directories where we house code and
// configuration used in the CI/CD pipeline
group "pipeline" {
@ -258,4 +307,14 @@ changed_files {
base_dir = ["ui"]
}
}
// The "zap_scan" group matches the Zap scanner
group "zap_scan" {
match {
contains = [
"security-scan-zap",
"zap_scan",
]
}
}
}

View file

@ -27,9 +27,6 @@ container {
triage {
suppress {
vulnerabilities = [
// We can't do anything about these two CVEs until a new Alpine container with busybox 1.38 is available.
"CVE-2025-46394",
"CVE-2024-58251",
"GO-2022-0635", // github.com/aws/aws-sdk-go@v1.x
]

View file

@ -9,11 +9,16 @@
schema = 1
active_versions {
version "1.21.x" {
version "2.x.x" {
ce_active = true
lts = true
}
version "1.20.x" {
version "1.21.x" {
ce_active = false
}
version "1.20.x" {
ce_active = false
}
@ -21,9 +26,4 @@ active_versions {
ce_active = false
lts = true
}
version "1.16.x" {
ce_active = false
lts = true
}
}

View file

@ -3,6 +3,524 @@
- [v1.0.0 - v1.9.10](CHANGELOG-pre-v1.10.md)
- [v0.11.6 and earlier](CHANGELOG-v0.md)
## 2.0.2
### June 05, 2026
BREAKING CHANGES:
* containers: Remove `cap_ipc_lock` capability on `vault` at build time to allow running Vault in common container runtimes. Vault in containers will no longer be able to call `mlock()` to lock memory. Operators should set `disable_mlock = true` in Vault's configuration. Runtime operators are advised to disable swapping to guarantee data safety.
* secrets/ssh: RSA key sizes are now limited to a maximum size of 8192 bits addressing CVE-2026-39829
CHANGES:
* core: Bump Go version to 1.26.4
* secrets/azure (enterprise): Update plugin to [v0.26.4+ent](https://github.com/hashicorp/vault-plugin-secrets-azure-enterprise/releases/tag/v0.26.4+ent)
BUG FIXES:
* plugins: Fix plugin signature verification failure with expired pgp key when registering a plugin.
* ui/transit: Fix key version dropdown selected state when editing a transit key.
## 2.0.1
### May 19, 2026
BREAKING CHANGES:
* containers: set cap_ipc_lock capability on vault at build time. Container runtimes will need to add `IPC_LOCK` capabilities when running the vault container.
SECURITY:
* api: Update golang.org/x/net to resolve GO-2026-4918"
* core/identity: reject wildcards in rendered identity templates
* core: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* core: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* core: Update github.com/apache/thrift to fix security vulnerability GHSA-wf45-q9ch-q8gh
* core: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* core: Update golang.org/x/net to resolve GO-2026-4918"
* core: Validate both `path` and `file_path` cannot be empty for requests to `sys/audit/{path}`
* sdk: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* sdk: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* sdk: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* sdk: Update golang.org/x/net to resolve GO-2026-4918"
CHANGES:
* auth/jwt: Update plugin to [v0.26.3](https://github.com/hashicorp/vault-plugin-auth-jwt/releases/tag/v0.26.3)
* core: Bump Go version to 1.26.3
* identity: Require `sudo` capability to invoke the identity entity merge API endpoint (`identity/entity/merge`).
* secrets/azure: Update plugin to [v0.26.2+ent](https://github.com/hashicorp/vault-plugin-secrets-azure-enterprise/releases/tag/v0.26.2+ent)
* secrets/openldap: Update plugin to [v0.18.1+ent](https://github.com/hashicorp/vault-plugin-secrets-openldap-enterprise/releases/tag/v0.18.1+ent)
FEATURES:
* **Billing metrics dashboard**: Create a new billing dashboard with responsive layout to display metric data.
* **Secrets Sync UI**: Added Workload Identity Federation (WIF) support in the UI for AWS, Azure, and GCP sync destinations
IMPROVEMENTS:
* api: Add `start_month` and `end_month` parameters to `/sys/billing/overview` endpoint to allow querying billing data for specific time ranges.
* api: Add migration_done_at_epoch to sys/seal-status response.
* consumption-billing: Add billing tracking for OS Local Account static roles to support consumption-based billing metrics and high-water mark (HWM) tracking.
* consumption-billing: Added consumption billing metrics for OIDC tokens.
* consumption-billing: Added consumption billing metrics for PKI External CA certificates.
* consumption-billing: Added consumption billing metrics for SPIFFE JWT tokens.
* consumption-billing: Enabled `sys/billing/overview` endpoint in admin namespace.
* consumption-billing: Float64 values returned by `sys/billing/overview` are now rounded to 4 decimal places.
* consumption-billing: Increased billing data retention from 2 months to 37 months. The `/sys/internal/billing/overview` API endpoint now returns 37 months of historical consumption billing data by default.
* consumption-billing: The `/sys/internal/billing/overview` API endpoint now always returns all metric types in the response, even when their values are zero. This ensures consistent response structure for easier client-side parsing.
* core (Enterprise): Sanitized config now shows kms_library config.
* core/seal (enterprise): Make it possible for new nodes to join a cluster configured with Seal High Availability.
* scim: The SCIM Group PATCH handler now supports the path field in the form members[value eq "id"] on remove operations.
* sdk: Expand support for docker test cluster options like seals, kms libraries, and entropy augmentation. DockerClusterNode.UpdateConfig now takes a full set of cluster options instead of just node config.
* sdk: add WIF and rotation helpers for checking if params were updated to allow
the consumer to know when changes need to be persisted to storage
* secrets/pki (enterprise): Allow SCEP to use an issuer that is backed by an RSA based PKCS#11 managed key
* secrets/transit: Change to using Trail of Bits libraries for PQC signature implementation in Transit
* ui/dashboard: Reorganized dashboard widgets to improve layout and usability. Updated widgets to use HDS table components for better consistency. Enhanced the Quick Actions card with frequently used links alongside existing actions.
* ui: Set pagination size to 10 for custom messages list view and toggle the "Apply filters" button visibility based on filter selection.
* ui: Update copy on merge entities page to specify entity ID is the required data input when merging entities.
* ui: add validations to the ACL visual policy editor to prevent it from saving policies with empty paths or capabilities.
BUG FIXES:
* auth/aws: fix bug where rotation and wif config updates were not persisted to storage
* client/ocsp: Adds a grace period to renew the cached entry for OCSP response.
* core: Fix failure to detect errors during storage writes of totp keys.
* database/mssql: Fix "sysadmin" requirement during lease revocation by replacing the undocumented `sp_msloginmappings` procedure with a granular metadata query. This allows the plugin to function with `VIEW ANY DEFINITION` instead of full `sysadmin` privileges.
* database/mssql: Fix dynamic secret revocation by executing custom statements as a single batch instead of splitting on semicolons
* database/snowflake: Fix WAL rollback issue for key-pair root credential rotation.
* database: prevent static role rotation and connection init from hanging indefinitely when database calls block by adding timeouts around UpdateUser and Initialize
* events (enterprise): Fix panic when replicating lease events.
* go-plugin: Upgrade go-plugin to fix a bug where file descriptors could be leaked when spawning external plugins
* identity: fixed a rare but possible data race issue with identities.
* sdk: Small bugfixes relating to docker test container cleanup and image building.
* secrets-sync (enterprise): Fix destination PATCH handling for WIF identity_token_ttl normalization and GCP service_account_email decoding.
* secrets/kmip (enterprise): Address a nil pointer within the invalidation handler for managed objects.
* secrets/ldap: enable proper license checking on 'openldap' plugin alias. This enables enterprise features when configuring mounts with the 'openldap' alias.
* secrets/pki (enterprise): Fix SCEP nonce logging in audit data.
* secrets/pki (enterprise): Include root CA in chain for CIEPS endpoints when root is the direct issuer, unless `remove_roots_from_chain` is true.
* secrets/pki: Remove invalid value from the supported list of ACME algorithms.
* ui: Add name field validation to LDAP create and edit roles forms.
* ui: Fix LDAP hierarchical role navigation in UI
* ui: Fix entities page to show success message after successfully editing an entity.
* ui: Fix secrets to secrets-engines redirect for bookmarked URLs.
* ui: Fixed custom messages list to display the expiration time on Inactive message badges.
* ui: Fixed sidebar navigation animation issues
* ui: Restore re-sizable columns for secrets and namespaces tables.
* ui: Update DR operation token generation to accept a primary root token for authentication.
* ui: Update KV max_version validation to disallow negative values.
## 2.0.0
### April 14, 2026
BREAKING CHANGES:
* sdk/helpers/docker: Migrate docker helpers from github.com/docker/docker to github.com/moby/moby. This was necessary as github.com/docker/docker is no longer maintained. Resolves GHSA-x744-4wpc-v9h2 and GHSA-pxq6-2prw-chj9.
SECURITY:
* Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* Upgrade `filippo.io/edwards25519` to v1.1.1 to resolve GO-2026-4503
* api/auth/gcp: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* api/auth: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* auth/aws: fix an issue where a user may be able to bypass authentication to Vault due to incorrect caching of the AWS client
* auth/cert: ensure that the certificate being renewed matches the certificate attached to the session.
* core: Correctly remove any Vault tokens from the Authorization header when this header is forwarded to plugin backends. The header will only be forwarded if "Authorization" is explicitly included in the list of passthrough request headers.
* core: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* core: Update github.com/aws/aws-sdk-go-v2/ to fix security vulnerability GHSA-xmrv-pmrh-hhx2.
* core: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Update github.com/hashicorp/go-getter to fix security vulnerability GHSA-92mm-2pjq-r785.
* core: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* core: reject URL-encoded paths that do not specify a canonical path
* http: Added configurable `max_token_header_size` listener option (default 8 KB) to bound the size of authentication token headers (`X-Vault-Token` and `Authorization: Bearer`), preventing a potential denial-of-service attack via oversized header contents. The stdlib-level `MaxHeaderBytes` backstop is also now set on the HTTP server. Set `max_token_header_size = -1` to disable the limit.
* sdk: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* sdk: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* ui: disable scarf analytics for ui builds
* vault/sdk: Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* vault/sdk: Upgrade `go.opentelemetry.io/otel/sdk` to v1.40.0 to resolve GO-2026-4394
* Update github.com/dvsekhvalnov/jose2go to fix security vulnerability CVE-2025-63811.
* go: update to golang/x/crypto to v0.45.0 to resolve GHSA-f6x5-jh6r-wrfv, GHSA-j5w8-q4qc-rx2x, GO-2025-4134 and GO-2025-4135.
CHANGES:
* secrets/ldap (enterprise): Static roles will be migrated from a plugin-managed queue to the Vault Enterprise Rotation Manager system. Static role migration progress can be checked and managed through a new static-migration endpoint. See the [LDAP documentation](https://developer.hashicorp.com/vault/docs/secrets/ldap#static-role-migration-to-rotation-manager) for more details on this process.
* audit: A new top-level key called `supplemental_audit_data` can now appear within audit entries of type "response" within the request and response data structures. These new fields can contain data that further describe the request/response data and are mainly used for non-JSON based requests and responses to help auditing. The `audit-non-hmac-request-keys` and `audit-non-hmac-response-keys` apply to keys within `supplemental_audit_data` to remove the HMAC of the field values if so desired.
* auth/alicloud: Update plugin to [v0.23.1](https://github.com/hashicorp/vault-plugin-auth-alicloud/releases/tag/v0.23.1)
* auth/azure: Update plugin to [v0.24.0](https://github.com/hashicorp/vault-plugin-auth-azure/releases/tag/v0.24.0)
* auth/cf: Update plugin to [v0.23.0](https://github.com/hashicorp/vault-plugin-auth-cf/releases/tag/v0.23.0)
* auth/gcp: Update plugin to [v0.23.1](https://github.com/hashicorp/vault-plugin-auth-gcp/releases/tag/v0.23.1)
* auth/jwt: Update plugin to [v0.26.1](https://github.com/hashicorp/vault-plugin-auth-jwt/releases/tag/v0.26.1)
* auth/kerberos: Update plugin to [v0.17.1](https://github.com/hashicorp/vault-plugin-auth-kerberos/releases/tag/v0.17.1)
* auth/kubernetes: Update plugin to [v0.24.1](https://github.com/hashicorp/vault-plugin-auth-kubernetes/releases/tag/v0.24.1)
* auth/oci: Update plugin to [v0.21.1](https://github.com/hashicorp/vault-plugin-auth-oci/releases/tag/v0.21.1)
* auth/saml: Update plugin to v0.8.1
* core/managed-keys (enterprise): The response to API endpoint GET sys/managed-keys/:type/:name now returns an array of string values for key usages, rather than an array of integer values. The strings used are 'encrypt' (1), 'decrypt' (2), 'sign' (3), 'verify' (4), 'wrap' (5), 'unwrap' (6), 'generate_random' (7), and 'mac' (8).
* core: Bump Go version to 1.26.2
* core: Vault now rejects paths that are not canonical, such as paths containing double slashes (`path//to/resource`)
* core: bump github.com/hashicorp/cap to v0.12.0
* core: secondary DR requests can now be authenticated using a root token generated on the primary.
* core: sys/generate-root and sys/replication/dr/secondary/generate-operation-token endpoints are now authenticated by default, with the old unauthenticated behaviour enabled by setting the new HCL config key enable_unauthenticated_access to include the value "generate-root" or "generate-operation-token" respectively.
* core: sys/rekey endpoints are now authenticated by default, with the old unauthenticated behaviour enabled by setting the new HCL config key enable_unauthenticated_access to include the value "rekey".
* database/couchbase: Update plugin to [v0.16.1](https://github.com/hashicorp/vault-plugin-database-couchbase/releases/tag/v0.16.1)
* database/elasticsearch: Update plugin to [v0.20.1](https://github.com/hashicorp/vault-plugin-database-elasticsearch/releases/tag/v0.20.1)
* database/mongodbatlas: Update plugin to [v0.17.1](https://github.com/hashicorp/vault-plugin-database-mongodbatlas/releases/tag/v0.17.1)
* database/redis-elasticache: Update plugin to [v0.9.1](https://github.com/hashicorp/vault-plugin-database-redis-elasticache/releases/tag/v0.9.1)
* database/redis: Update plugin to [v0.8.1](https://github.com/hashicorp/vault-plugin-database-redis/releases/tag/v0.8.1)
* database/snowflake: Update plugin to [v0.16.0](https://github.com/hashicorp/vault-plugin-database-snowflake/releases/tag/v0.16.0)
* license utilization reporting (enterprise): Manual reporting bundles generated by `vault operator utilization` have a changed format. Notably they contain an array of `snapshot_records` instead of `snapshots`. The `decoded_snapshot` field in each record contains the human-readable data that was previously in the `snapshots` array.
* mfa/duo: Upgrade duo_api_golang client to 0.2.0 to include the new Duo certificate authorities
* packaging: Container images are now exported using a compressed OCI image layout.
* packaging: UBI container images are now built on the UBI 10 minimal image.
* secrets/ad: Update plugin to [v0.22.1](https://github.com/hashicorp/vault-plugin-secrets-ad/releases/tag/v0.22.1)
* secrets/alicloud: Update plugin to [v0.22.1](https://github.com/hashicorp/vault-plugin-secrets-alicloud/releases/tag/v0.22.1)
* secrets/azure: Update azure enterprise secrets plugin to include static roles.
* secrets/azure: Update plugin to v0.25.1+ent. Improves retry handling during Azure application and service principal creation to reduce transient failures.
* secrets/azure: Update plugin to v0.26.1+ent
* secrets/gcp: Update plugin to [v0.24.0](https://github.com/hashicorp/vault-plugin-secrets-gcp/releases/tag/v0.24.0)
* secrets/gcpkms: Update plugin to [v0.23.0](https://github.com/hashicorp/vault-plugin-secrets-gcpkms/releases/tag/v0.23.0)
* secrets/keymgmt: Update plugin to [v0.19.0+ent](https://github.com/hashicorp/vault-plugin-secrets-keymgmt/releases/tag/v0.19.0+ent)
* secrets/kmip: Update plugin to v0.20.0
* secrets/kubernetes: Update plugin to [v0.13.1](https://github.com/hashicorp/vault-plugin-secrets-kubernetes/releases/tag/v0.13.1)
* secrets/kv: Update plugin to [v0.26.2](https://github.com/hashicorp/vault-plugin-secrets-kv/releases/tag/v0.26.2)
* secrets/mongodbatlas: Update plugin to [v0.17.1](https://github.com/hashicorp/vault-plugin-secrets-mongodbatlas/releases/tag/v0.17.1)
* secrets/openldap: Update plugin to [v0.18.0](https://github.com/hashicorp/vault-plugin-secrets-openldap/releases/tag/v0.18.0)
* secrets/pki: sign-verbatim endpoints no longer ignore basic constraints extension in CSRs, using them in generated certificates if isCA=false or returning an error if isCA=true
* secrets/terraform: Update plugin to [v0.14.1](https://github.com/hashicorp/vault-plugin-secrets-terraform/releases/tag/v0.14.1)
* secure-plugin-api: Update to v0.2.0
* storage: Upgrade aerospike client library to v8.
* ui/secrets: Secrets engines url paths renamed from '/secrets' to '/secrets-engines'
* ui: Remove ability to bulk delete secrets engines from the list view.
FEATURES:
* **PKI External CA (Enterprise)**: A new plugin that provides the ability to acquire PKI certificates from Public CA providers through the ACME protocol
* **IBM PAO License Integration**: Added IBM PAO license support, allowing usage of Vault Enterprise with an IBM PAO license key. A new configuration stanza `license_entitlement` is required in the Vault config to use an IBM license. For more details, see the [License documentation](https://developer.hashicorp.com/vault/docs/license#ibm-pao-license-keys).
* **KMIP Bring Your Own CA**: Add new API to manage multiple CAs for client verification and make it possible to import external CAs.
* **LDAP Secrets Engine Enterprise Plugin**: Add the new LDAP Secrets Engine Enterprise plugin. This enterprise version adds support for self-managed static roles and Rotation Manager support for automatic static role rotation. New plugin configurations can be set as "self managed", skipping the requirement for a bindpass field and allowing static roles to use their own password to rotate their credential. Automated static role credential rotation supports fine-grained scheduled rotations and retry policies through Vault Enterprise.
* **Login MFA TOTP Self-Enrollment (Enterprise)**: Simplify creation of login MFA TOTP credentials for users, allowing them to self-enroll MFA TOTP using a QR code (TOTP secret) generated during login. The new functionality is configurable on the TOTP login MFA method configuration screen and via the `enable_self_enrollment` parameter in the API.
* **Plugins (Enterprise)**: Allow overriding pinned version when creating and updating database engines
* **Plugins (Enterprise)**: Allow overriding pinned version when enabling and tuning auth and secrets backends
* **SCIM 2.0 Identity Provisioning Beta (Beta/Enterprise)**: Adds beta support for Vault to act as a SCIM 2.0 server, allowing external management of Vault entities, aliases and groups.
* **Template Integration for PublicPKICA**: Vault Agent templates are now automatically re-rendered when a PKI external CA certificate is issued or renewed.
* **UI ACL Policies intro**: Onboarding intro which provides feature context to users.
* **UI Authentication methods intro**: Onboarding intro which provides feature context to users.
* **UI Namespace Wizard (Enterprise)**: Onboarding wizard which provides advice to users based on their intended usage and guides them through namespace creation.
* **UI Policy Generator (Enterprise)**: Adds policy generator flyout to KV V2 and PKI secrets engines prepopulated with relevant API requests for each page.
* **UI Secret engines intro**: Onboarding intro which provides feature context to users.
* **UI TLS Certificate login**: Add UI login support for the TLS certificate (cert) authentication.
* **UI: Hashi-Built External Plugin Support**: Recognize and support Hashi-built plugins when run as external binaries
* **UI: Hashi-Built External Plugin Support**: Support external plugin version updates via the GUI.
* **UI: Mount versioned external plugins**: Adds ability to mount previously registered, external plugins and specify a version when enabling secrets engines.
* **Vault Agent: ACME protocol support**: Add support to natively support Public CA ACME workflows
* secrets-sync: implemented workload identity federation support for secrets sync flows.
IMPROVEMENTS:
* **Secrets Engines UI improvement**: Updated configuration views and added tune support for configurations across all compatible secrets engines.
* **Sidebar UI improvement**: Add top navbar, update sidebar navigation structure, and update page headers.
* api: Add a SHA256 sum field to the json list response for external plugins.
* api: Added sudo-permissioned `sys/reporting/scan` endpoint which will output a set of files containing information about Vault state to the location specified by the `reporting_scan_directory` config item.
* auth/ldap: Require non-empty passwords on login command to prevent unauthenticated access to Vault.
* config/listener: logs warnings on invalid x-forwarded-for configurations.
* consumption-billing: Adds a new `sys/billing/overview` endpoint that returns current and previous month consumption billing metrics. Accessible via API client method `client.Sys().BillingOverview()`.
* core (enterprise): Add common_criteria_mode feature_flags setting which limits listener TLS cipher suites.
* core (enterprise): Added a new telemetry metric `vault.core.license.termination_time_epoch`.
* core (enterprise): enable rotation manager to send rotation information required by plugin backends during registration and rotation operations. This allows plugin backends to have the necessary context for managing their rotation state effectively.
* core (enterprise): enable rotation manager to use configurable retry policies to limit the retry behavior for rotation entries and include an orphaning mechanism to handle entries that exceed the maximum retry attempts.
* core (enterprise): improve rotation manager error handling by implementing a backoff when re-queueing failed rotations
* core/identity: Add two new fields to the alias API, external_id and issuer. These fields do not inherently do anything meaningful, and are part of a future feature.
* core/managed-keys (enterprise): Allow GCP managed keys to leverage workload identity federation credentials
* core/metrics: Reading and listing from a snapshot are now tracked via the `vault.route.read-snapshot.{mount_point}` and `vault.route.list-snapshot.{mount_point}` metrics.
* core/seal: Enhance sys/seal-backend-status to provide more information about seal backends.
* core: check rotation manager queue every 5 seconds instead of 10 seconds to improve responsiveness
* dockerfile: container will now run as vault user by default
* events (enterprise): Add event notifications support for lease events.
* events (enterprise): Forward event notifications from primary to secondary clusters
* kmip (enterprise): Add experimental API to execute KMIP requests.
* license utilization reporting (enterprise): Add metrics for the number of issued PKI certificates.
* license utilization reporting (enterprise): Utilization reports now include new license metadata fields `issuer`, `edition`, `add_ons`, `license_start_time`, `license_expiration_time`, and `license_termination_time`.
* license utilization reporting: Added consumption billing metrics.
* pki: Reject obviously unsafe validation targets during ACME HTTP-01 and TLS-ALPN-01 challenge verification
* policies: add warning about list comparison when using allowed_parameters or denied_parameters
* rotation: Ensure rotations for shared paths only execute on the Primary cluster's active node. Ensure rotations for local paths execute on the cluster-local active node.
* sdk/rotation: Prevent rotation attempts on read-only storage
* sdk: Add NewTestDockerCluster support for running external plugins within the same container as the server.  Also add support for those plugins to expose their own listeners, as KMIP does.
* sdk: Add alias_metadata to tokenutil fields that auth method roles use.
* secret-sync (enterprise): Added telemetry counters for reconciliation loop operations, including the number of corrections detected,  retry attempts, and operation outcomes (success or failure with internal/external cause labels).
* secret-sync (enterprise): Added telemetry counters for sync/unsync operations with status breakdown by destination type, and exposed operation counters in the destinations list API response.
* secret-sync: add parallelization support to sync and unsync operations for secret-key granularity associations
* secrets-pki (enterprise): Add response data in a parsed format to the audit log for enrollment protocols.
* secrets-sync (enterprise): Added support for a boolean force_delete flag (default: false). When set to true, this flag allows deletion of a destination even if its associations cannot be unsynced. This option should be used only as a last-resort deletion mechanism, as any secrets already synced to the external provider will remain orphaned and require manual cleanup.
* secrets-sync (enterprise): Improved the user experience during mount lifecycle changes by triggering immediate unsyncing of external secrets when a secrets engine mount is deleted or disabled. By moving this logic from the background reconciliation loop to a direct callback, the system prevents perceived "leaks" and ensures external secret resources are cleaned up synchronously with the Vault unmount.
* secrets/database: Add root rotation support for Snowflake database secrets engines using key-pair credentials.
* secrets/keymgmt (enterprise): Add support for multi-region AWS KMS keys.
* secrets/kmip (Enterprise): Obey configured best_effort_wal_wait_duration when forwarding kmip requests.
* secrets/ldap: Users can now fully manage and tune the LDAP secrets engine. This includes the ability to view, edit, and configure the LDAP engine.
* secrets/pki (enterprise): Return the POSTPKIOperation capability within SCEP GetCACaps endpoint for better legacy client support.
* secrets/pki (enterprise): Validate entire chain in common criteria mode; add field to enable time checks on validation
* secrets/pki (enterprise): When the common_criteria_mode feature flag is enabled, NotBefore will always be treated as zero.
* secrets/pki (enterprise): When the common_criteria_mode feature flag is enabled, enforce a minimum set of key usages for each ext key usage set based on RFC 5280 Section 4.2.1.12 during PKI role updates.
* secrets/pki: Add ACME configuration fields challenge_permitted_ip_ranges and challenge_excluded_ip_ranges configuration to control which IP addresses are allowed or disallowed for challenge validation.
* secrets/pki: Add Freshest CRL extension (Delta CRL Distribution Points) to base CRLs
* secrets/pki: Avoid loading issuer information multiple times per leaf certificate signing
* secrets/pki: Include the certificate's AuthorityKeyID in response fields for API endpoints that issue, sign, or fetch certs.
* secrets/pki: OCSP populate details of the response within the new `supplemental_audit_data` section of audit log response entries. Details such as issuer_id, next_update, ocsp_status, serial_number, revoked_at will appear as hmac values by default unless added to the mount's `audit-non-hmac-response-keys` set of keys.
* secrets/pki: when in common criteria mode, don't allow upload of certificates without a chain of trust.
* secrets/transit, core: Boost the limit of random bytes retrievable via random byte APIs.  And add the option to get PRNG random bytes seeded by random sources. Note that requests for large numbers of bytes will increase Vault memory usage accordingly.
* secrets/transit: Improve import errors for non-PKCS#8 keys to clearly require PKCS#8.
* sys (enterprise): Add sys/billing/certificates API endpoint to retrieve the number of issued PKI certificates.
* transit (enterprise): Add context parameter to datakeys and derived-keys endpoint, to allow derived key encryption of the DEKs.
* ui/activity (enterprise): Add clarifying text to explain the "Initial Usage" column will only have timestamps for clients initially used after upgrading to version 1.21
* ui/activity (enterprise): Allow manual querying of client usage if there is a problem retrieving the license start time.
* ui/activity (enterprise): Reduce requests to the activity export API by only fetching new data when the dashboard initially loads or is manually refreshed.
* ui/activity (enterprise): Support filtering months dropdown by ISO timestamp or display value.
* ui/activity: Display total instead of new monthly clients for HCP managed clusters
* ui/pki: Adds support to configure `server_flag`, `client_flag`, `code_signing_flag`, and `email_protection_flag` parameters for creating/updating a role.
* ui: Add "Configuration path" and "Configuration metadata path" fields to KV v2 secret paths page showing paths without /v1/ prefix for use in policies, Vault Agent configurations, and other tools that reference the logical path.
* ui: After clicking Save or Discard in the unsaved changes modal, the user will now navigate to the intended destination link.
* ui: Display errors consistently across the application and show API messages where available.
* ui: Update the sidenav design and add top navbar.
BUG FIXES:
* activity (enterprise): sys/internal/counters/activity outputs the correct mount type when called from a non root namespace
* agent/pkiexternalca: Fix token distribution to PKI system and HTTP-01 challenge server shutdown preventing certificate acquisition and retries
* agent: Fix Vault Agent discarding cached tokens on transient server errors instead of retrying
* audit/file: The logic preventing setting of executable bits on audit devices was enforced at unseal instead of just at new audit device creation, causing an error at unseal if an existing audit device had exec permissions.  The logic now warns and clears exec bits to prevent unseal errors.
* auth/approle (enterprise): Fixed bug that prevented periodic tidy running on performance secondary
* auth/approle (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/aws (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/cert (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/gcp: Fix intermittent context canceled failures for Workload Identity Federation (WIF) authentication
* auth/github (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/ldap (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/okta (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/radius (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/scep (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth/spiffe: Address an issue updating a role with overlapping workload_id_pattern values it previously contained.
* auth/userpass (enterprise): Role parameter `alias_metadata` now populates alias custom metadata field instead of alias metadata.
* auth: fixed panic when suppling integer as a lease_id in renewal.
* core (Enterprise): fix unaligned atomic panic in replication code on 32-bit platforms.
* core (enterprise): Avoid duplicate seal rewrapping, and ensure that cluster secondaries rewrap after a seal migration.
* core (enterprise): Buffer the POST body on binary paths to allow re-reading on non-logical forwarding attempts. Addresses an issue for SCEP, EST and CMPv2 certificate issuances with slow replication of entities
* core (enterprise): Fix crash when seal HSM is disconnected
* core/activitylog (enterprise): Resolve a stability issue where Vault Enterprise could encounter a panic during month-end billing activity rollover.
* core/identity (enterprise): Fix excessive logging when updating existing aliases
* core/managed-keys (enterprise): Fix a bug that prevented the max_parallel field of PKCS#11 managed keys from being updated.
* core/managed-keys (enterprise): Fix a problem that prevented 'mac' and 'generate_random' key usages from being set.
* core/managed-keys (enterprise): client credentials should not be required when using Azure Managed Identities in managed keys.
* core/rotation: avoid shifting timezones by ignoring cron.SpecSchedule
* core: Fix bug where background thread to clean the MFA response auth queue runs on PR and DR secondaries.
* core: interpret all new rotation manager rotation_schedules as UTC to avoid inadvertent use of tz-local
* default-auth: Fix issue when specifying "root" explicitly in Default Auth UI
* events (enterprise): Fix missed events when multiple event clients specify the same namespace and event type filters and one client disconnects.
* http: skip JSON limit parsing on cluster listener
* identity: Fix issue where Vault may consume more memory than intended under heavy authentication load.
* identity: Repair the integrity of duplicate and/or dangling entity aliases.
* kmip (enterprise): Fix a bug that would cause a panic on Create Key Pair operations that specify no attributes for the private or the public key.
* ldap auth (enterprise): Fix root password rotation for Active Directory by implementing UTF-16LE encoding and schema-specific handling. Adds new 'schema' config field (defaults to 'openldap' for backward compatibility).
* logging: Fixed an issue where the `log_requests_level` configuration was not respected on a SIGHUP reload when set to "off" or removed from the config file.
* plugins (enterprise): Fix bug where requests to external plugins that modify storage weren't populating the X-Vault-Index response header.
* plugins: Fix regression in plugin sdk where external plugins may panic when doing storage writes/deletes.
* quotas: Vault now protects plugins with ResolveRole operations from panicking on quota creation.
* replication (enterprise): fix rare panic due to race when enabling a secondary with Consul storage.
* rotation: Fix a bug where a performance secondary would panic if a write was made to a local mount
* secret sync (enterprise): fix panic in set-association API when using Vault Proxy with token-bound CIDRs. The panic occurred due to missing connection information during CIDR validation.
* secret sync (enterprise): fixed panic due to nil pointer dereference when reconciling associations. Added guard checks to prevent access to nil references, making association handling more robust.
* secret-sync (enterprise): Fix race condition in secretsSetRemoveHandler by serializing MemDB transaction access.
* secret-sync (enterprise): Improved unsync error handling by treating cases where the destination no longer exists as successful.
* secrets (pki): Allow issuance of certificates without the server_flag key usage from SCEP, EST and CMPV2 protocols.
* secrets-sync (enterprise): Corrected a bug where the deletion of the latest KV-V2 secret version caused the associated external secret to be deleted entirely. The sync job now implements a version fallback mechanism to find and sync the highest available active version, ensuring continuity and preventing the unintended deletion of the external secret resource.
* secrets-sync (enterprise): Fix issue where secrets were not properly un-synced after destination config changes.
* secrets-sync (enterprise): Fix issue where sync store deletion could be attempted when sync is disabled.
* secrets-sync: secrets-sync APIs return appropriate client side error codes when the request is invalid.
* secrets/azure: Ensure proper installation of the Azure enterprise secrets plugin.
* secrets/pki (enterprise): Address cache invalidation issues with CMPv2 on performance standby nodes.
* secrets/pki (enterprise): Address issues using SCEP on performance standby nodes failing due to configuration invalidation issues along with errors writing to storage
* secrets/pki (enterprise): Fix SCEP related digest errors when requests contained compound octet strings
* secrets/pki (enterprise): Modify the SCEP GetCACaps endpoint to dynamically reflect the configured encryption and digest algorithms.
* secrets/pki: Return error when issuing/signing certs whose NotAfter is before NotBefore or whose validity period isn't contained by the CA's.
* secrets/pki: The root/sign-intermediate endpoint max_path_length parameter is now restricted by the signing CA's max_path_length if set.
* secrets/pki: The root/sign-intermediate endpoint should not fail when provided a CSR with a basic constraint extension containing isCa set to true
* secrets/pki: Warn if the Country field on roles and when generating CAs is not ISO 3166 compliant
* secrets/pki: allow glob-style DNS names in alt_names.
* secrets/transit (enterprise): Fix bugs that prevent using ML-DSA and SLH-DSA keys after reading the policy from storage.
* secrets/transit: Fix nil pointer panic when restoring malformed backup data.
* ui (enterprise): Fix KV v2 not displaying secrets in namespaces.
* ui (enterprise): Fixes login form so input renders correctly when token is a preferred login method for a namespace.
* ui/pki: Fixes certificate parsing of the `key_usage` extension so details accurately reflect certificate values.
* ui/pki: Fixes creating and updating a role so `basic_constraints_valid_for_non_ca` is correctly set.
* ui: Fix KV v2 metadata list request failing for policies without a trailing slash in the path.
* ui: Fix secrets table pagination when switching page sizes.
* ui: Fixes login form so `?with=<path>` query param correctly displays only the specified mount when multiple mounts of the same auth type are configured with `listing_visibility="unauth"`
* ui: Resolved a regression that prevented users with create and update permissions on KV v1 secrets from opening the edit view. The UI now correctly recognizes these capabilities and allows editing without requiring full read access.
* ui: Reverts Kubernetes CA Certificate auth method configuration form field type to file selector
* ui: Update LDAP accounts checked-in table to display hierarchical LDAP libraries
* ui: Update LDAP library count to reflect the total number of nodes instead of number of directories
* ui: fix renew token button rendering for denied renew-self.
* ui: remove unnecessary 'credential type' form input when generating AWS secrets
## 1.21.7 Enterprise
### June 05, 2026
BREAKING CHANGES:
* containers: Remove `cap_ipc_lock` capability on `vault` at build time to allow running Vault in common container runtimes. Vault in containers will no longer be able to call `mlock()` to lock memory. Operators should set `disable_mlock = true` in Vault's configuration. Runtime operators are advised to disable swapping to guarantee data safety.
* secrets/ssh: RSA key sizes are now limited to a maximum size of 8192 bits addressing CVE-2026-39829
CHANGES:
* core: Bump Go version to 1.25.11
* secrets/azure (enterprise): Update plugin to [v0.25.3+ent](https://github.com/hashicorp/vault-plugin-secrets-azure-enterprise/releases/tag/v0.25.3+ent)
BUG FIXES:
* plugins: Fix plugin signature verification failure with expired pgp key when registering a plugin.
* ui/transit: Fix key version dropdown selected state when editing a transit key.
## 1.21.6 Enterprise
### May 19, 2026
BREAKING CHANGES:
* containers: set cap_ipc_lock capability on vault at build time. Container runtimes will need to add `IPC_LOCK` capabilities when running the vault container.
SECURITY:
* api: Update golang.org/x/net to resolve GO-2026-4918"
* core/identity: reject wildcards in rendered identity templates
* core: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* core: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* core: Update github.com/apache/thrift to fix security vulnerability GHSA-wf45-q9ch-q8gh
* core: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* core: Update golang.org/x/net to resolve GO-2026-4918"
* core: Validate both `path` and `file_path` cannot be empty for requests to `sys/audit/{path}`
* sdk: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* sdk: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* sdk: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* sdk: Update golang.org/x/net to resolve GO-2026-4918"
CHANGES:
* auth/jwt: Update plugin to [v0.25.1](https://github.com/hashicorp/vault-plugin-auth-jwt/releases/tag/v0.25.1)
* core: Bump Go version to 1.25.10
* identity: Require `sudo` capability to invoke the identity entity merge API endpoint (`identity/entity/merge`).
* secrets/azure: Update plugin to [v0.25.2+ent](https://github.com/hashicorp/vault-plugin-secrets-azure/releases/tag/v0.25.2+ent)
IMPROVEMENTS:
* api: Add migration_done_at_epoch to sys/seal-status response.
* core (Enterprise): Sanitized config now shows kms_library config.
* core/seal (enterprise): Make it possible for new nodes to join a cluster configured with Seal High Availability.
* sdk: Expand support for docker test cluster options like seals, kms libraries, and entropy augmentation. DockerClusterNode.UpdateConfig now takes a full set of cluster options instead of just node config.
* secrets/pki (enterprise): Allow SCEP to use an issuer that is backed by an RSA based PKCS#11 managed key
* ui: `unsafe-inline` is no longer included in the `style-src` CSP directive.
BUG FIXES:
* client/ocsp: Adds a grace period to renew the cached entry for OCSP response.
* database/mssql: Fix "sysadmin" requirement during lease revocation by replacing the undocumented `sp_msloginmappings` procedure with a granular metadata query. This allows the plugin to function with `VIEW ANY DEFINITION` instead of full `sysadmin` privileges.
* database/mssql: Fix dynamic secret revocation by executing custom statements as a single batch instead of splitting on semicolons
* database/snowflake: Fix WAL rollback issue for key-pair root credential rotation.
* database: prevent static role rotation and connection init from hanging indefinitely when database calls block by adding timeouts around UpdateUser and Initialize
* go-plugin: Upgrade go-plugin to fix a bug where file descriptors could be leaked when spawning external plugins
* identity: fixed a rare but possible data race issue with identities.
* plugins/database/hana: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL identifiers before ALTER USER and DROP USER statements.
plugins/database/redshift: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL string literals when invoking terminateloop(...), preventing statement-structure manipulation.
* sdk: Small bugfixes relating to docker test container cleanup and image building.
* secrets/kmip (enterprise): Address a nil pointer within the invalidation handler for managed objects.
* secrets/pki (enterprise): Include root CA in chain for CIEPS endpoints when root is the direct issuer, unless `remove_roots_from_chain` is true.
* ui: Fix LDAP check-out capabilities check.
* ui: Fix entities page to show success message after successfully editing an entity.
* ui: Fix secrets table pagination when switching page sizes.
* ui: Fixed custom messages list to display the expiration time on Inactive message badges.
* ui: Restore re-sizable columns for secrets and namespaces tables.
* ui: Update KV max_version validation to disallow negative values.
## 1.21.5 Enterprise
### April 14, 2026
BREAKING CHANGES:
* sdk/helpers/docker: Migrate docker helpers from github.com/docker/docker to github.com/moby/moby. This was necessary as github.com/docker/docker is no longer maintained. Resolves GHSA-x744-4wpc-v9h2 and GHSA-pxq6-2prw-chj9.
SECURITY:
* api/auth/gcp: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* api/auth: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Correctly remove any Vault tokens from the Authorization header when this header is forwarded to plugin backends. The header will only be forwarded if "Authorization" is explicitly included in the list of passthrough request headers.
* core: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* core: Update github.com/aws/aws-sdk-go-v2/ to fix security vulnerability GHSA-xmrv-pmrh-hhx2.
* core: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Update github.com/hashicorp/go-getter to fix security vulnerability GHSA-92mm-2pjq-r785.
* core: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* core: reject URL-encoded paths that do not specify a canonical path
* sdk: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* sdk: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
CHANGES:
* core: Bump Go version to 1.25.9
* core: Vault now rejects paths that are not canonical, such as paths containing double slashes (`path//to/resource`)
IMPROVEMENTS:
* config/listener: logs warnings on invalid x-forwarded-for configurations.
* dockerfile: container will now run as vault user by default
* events (enterprise): Forward event notifications from primary to secondary clusters
* pki: Reject obviously unsafe validation targets during ACME HTTP-01 and TLS-ALPN-01 challenge verification
* secrets/pki: Add ACME configuration fields challenge_permitted_ip_ranges and challenge_excluded_ip_ranges configuration to control which IP addresses are allowed or disallowed for challenge validation.
* secrets/pki: Add Freshest CRL extension (Delta CRL Distribution Points) to base CRLs
* secrets/transit: Improve import errors for non-PKCS#8 keys to clearly require PKCS#8.
* transit (enterprise): Add context parameter to datakeys and derived-keys endpoint, to allow derived key encryption of the DEKs.
BUG FIXES:
* audit/file: The logic preventing setting of executable bits on audit devices was enforced at unseal instead of just at new audit device creation, causing an error at unseal if an existing audit device had exec permissions. The logic now warns and clears exec bits to prevent unseal errors.
* auth/gcp: Fix intermittent context canceled failures for Workload Identity Federation (WIF) authentication
* core (Enterprise): fix unaligned atomic panic in replication code on 32-bit platforms.
* core/managed-keys (enterprise): Fix a bug that prevented the max_parallel field of PKCS#11 managed keys from being updated.
* events (enterprise): Fix missed events when multiple event clients specify the same namespace and event type filters and one client disconnects.
* identity: Repair the integrity of duplicate and/or dangling entity aliases.
* ldap auth (enterprise): Fix root password rotation for Active Directory by implementing UTF-16LE encoding and schema-specific handling. Adds new 'schema' config field (defaults to 'openldap' for backward compatibility).
* secret sync (enterprise): fix panic in set-association API when using Vault Proxy with token-bound CIDRs. The panic occurred due to missing connection information during CIDR validation.
* secret sync (enterprise): fixed panic due to nil pointer dereference when reconciling associations. Added guard checks to prevent access to nil references, making association handling more robust.
* secret-sync (enterprise): Fix race condition in secretsSetRemoveHandler by serializing MemDB transaction access.
* secrets/pki: The root/sign-intermediate endpoint max_path_length parameter is now restricted by the signing CA's max_path_length if set.
* secrets/transit (enterprise): Fix bugs that prevent using ML-DSA and SLH-DSA keys after reading the policy from storage.
## 1.21.4
### March 05, 2026
SECURITY:
* Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* Upgrade `filippo.io/edwards25519` to v1.1.1 to resolve GO-2026-4503
* vault/sdk: Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* vault/sdk: Upgrade `go.opentelemetry.io/otel/sdk` to v1.40.0 to resolve GO-2026-4394
CHANGES:
* core: Bump Go version to 1.25.7
* mfa/duo: Upgrade duo_api_golang client to 0.2.0 to include the new Duo certificate authorities
* ui: Remove ability to bulk delete secrets engines from the list view.
IMPROVEMENTS:
* core/seal: Enhance sys/seal-backend-status to provide more information about seal backends.
* secrets/kmip (Enterprise): Obey configured best_effort_wal_wait_duration when forwarding kmip requests.
* secrets/pki (enterprise): Return the POSTPKIOperation capability within SCEP GetCACaps endpoint for better legacy client support.
BUG FIXES:
* core (enterprise): Buffer the POST body on binary paths to allow re-reading on non-logical forwarding attempts. Addresses an issue for SCEP, EST and CMPv2 certificate issuances with slow replication of entities
* core/identity (enterprise): Fix excessive logging when updating existing aliases
* core/managed-keys (enterprise): client credentials should not be required when using Azure Managed Identities in managed keys.
* plugins (enterprise): Fix bug where requests to external plugins that modify storage weren't populating the X-Vault-Index response header.
* secrets (pki): Allow issuance of certificates without the server_flag key usage from SCEP, EST and CMPV2 protocols.
* secrets/pki (enterprise): Address cache invalidation issues with CMPv2 on performance standby nodes.
* secrets/pki (enterprise): Address issues using SCEP on performance standby nodes failing due to configuration invalidation issues along with errors writing to storage
* secrets/pki (enterprise): Modify the SCEP GetCACaps endpoint to dynamically reflect the configured encryption and digest algorithms.
* secrets/pki: The root/sign-intermediate endpoint should not fail when provided a CSR with a basic constraint extension containing isCa set to true
* secrets/pki: allow glob-style DNS names in alt_names.
## 1.21.3
### February 05, 2026
@ -327,6 +845,159 @@ BUG FIXES:
* ui: Revert camelizing of parameters returned from `sys/internal/ui/mounts` so mount paths match serve value
* ui: Fixes permissions for hiding and showing sidebar navigation items for policies that include special characters: `+`, `*`
## 1.20.12 Enterprise
### June 05, 2026
BREAKING CHANGES:
* containers: Remove `cap_ipc_lock` capability on `vault` at build time to allow running Vault in common container runtimes. Vault in containers will no longer be able to call `mlock()` to lock memory. Operators should set `disable_mlock = true` in Vault's configuration. Runtime operators are advised to disable swapping to guarantee data safety.
* secrets/ssh: RSA key sizes are now limited to a maximum size of 8192 bits addressing CVE-2026-39829
CHANGES:
* core: Bump Go version to 1.25.11
BUG FIXES:
* plugins: Fix plugin signature verification failure with expired pgp key when registering a plugin.
## 1.20.11 Enterprise
### May 19, 2026
BREAKING CHANGES:
* containers: set cap_ipc_lock capability on vault at build time. Container runtimes will need to add `IPC_LOCK` capabilities when running the vault container.
SECURITY:
* api: Update golang.org/x/net to resolve GO-2026-4918"
* core/identity: reject wildcards in rendered identity templates
* core: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* core: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* core: Update github.com/apache/thrift to fix security vulnerability GHSA-wf45-q9ch-q8gh
* core: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* core: Update golang.org/x/net to resolve GO-2026-4918"
* core: Validate both `path` and `file_path` cannot be empty for requests to `sys/audit/{path}`
* sdk: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* sdk: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* sdk: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* sdk: Update golang.org/x/net to resolve GO-2026-4918"
CHANGES:
* auth/jwt: Update plugin to [v0.24.2](https://github.com/hashicorp/vault-plugin-auth-jwt/releases/tag/v0.24.2)
* core: Bump Go version to 1.25.10
* identity: Require `sudo` capability to invoke the identity entity merge API endpoint (`identity/entity/merge`).
IMPROVEMENTS:
* api: Add migration_done_at_epoch to sys/seal-status response.
* core (Enterprise): Sanitized config now shows kms_library config.
* core/seal (enterprise): Make it possible for new nodes to join a cluster configured with Seal High Availability.
* sdk: Expand support for docker test cluster options like seals, kms libraries, and entropy augmentation. DockerClusterNode.UpdateConfig now takes a full set of cluster options instead of just node config.
* secrets/pki (enterprise): Allow SCEP to use an issuer that is backed by an RSA based PKCS#11 managed key
* ui: `unsafe-inline` is no longer included in the `style-src` CSP directive.
BUG FIXES:
* client/ocsp: Adds a grace period to renew the cached entry for OCSP response.
* core: Fix failure to detect errors during storage writes of totp keys.
* database/mssql: Fix "sysadmin" requirement during lease revocation by replacing the undocumented `sp_msloginmappings` procedure with a granular metadata query. This allows the plugin to function with `VIEW ANY DEFINITION` instead of full `sysadmin` privileges.
* database/mssql: Fix dynamic secret revocation by executing custom statements as a single batch instead of splitting on semicolons
* database/snowflake: Fix WAL rollback issue for key-pair root credential rotation.
* database: prevent static role rotation and connection init from hanging indefinitely when database calls block by adding timeouts around UpdateUser and Initialize
* go-plugin: Upgrade go-plugin to fix a bug where file descriptors could be leaked when spawning external plugins
* identity: fixed a rare but possible data race issue with identities.
* plugins/database/hana: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL identifiers before ALTER USER and DROP USER statements.
plugins/database/redshift: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL string literals when invoking terminateloop(...), preventing statement-structure manipulation.
* sdk: Small bugfixes relating to docker test container cleanup and image building.
* secrets/kmip (enterprise): Address a nil pointer within the invalidation handler for managed objects.
* secrets/pki (enterprise): Include root CA in chain for CIEPS endpoints when root is the direct issuer, unless `remove_roots_from_chain` is true.
* ui/transit: Fix key version dropdown selected state when editing a transit key.
* ui: Fix LDAP check-out capabilities check.
* ui: Fix entities page to show success message after successfully editing an entity.
## 1.20.10 Enterprise
### April 14, 2026
BREAKING CHANGES:
* sdk/helpers/docker: Migrate docker helpers from github.com/docker/docker to github.com/moby/moby. This was necessary as github.com/docker/docker is no longer maintained. Resolves GHSA-x744-4wpc-v9h2 and GHSA-pxq6-2prw-chj9.
SECURITY:
* api/auth/gcp: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* api/auth: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Correctly remove any Vault tokens from the Authorization header when this header is forwarded to plugin backends. The header will only be forwarded if "Authorization" is explicitly included in the list of passthrough request headers.
* core: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* core: Update github.com/aws/aws-sdk-go-v2/ to fix security vulnerability GHSA-xmrv-pmrh-hhx2.
* core: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Update github.com/hashicorp/go-getter to fix security vulnerability GHSA-92mm-2pjq-r785.
* core: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* core: reject URL-encoded paths that do not specify a canonical path
* sdk: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* sdk: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
CHANGES:
* core: Bump Go version to 1.25.9
* core: Vault now rejects paths that are not canonical, such as paths containing double slashes (`path//to/resource`)
IMPROVEMENTS:
* config/listener: logs warnings on invalid x-forwarded-for configurations.
* dockerfile: container will now run as vault user by default
* pki: Reject obviously unsafe validation targets during ACME HTTP-01 and TLS-ALPN-01 challenge verification
* secrets/pki: Add ACME configuration fields challenge_permitted_ip_ranges and challenge_excluded_ip_ranges configuration to control which IP addresses are allowed or disallowed for challenge validation.
* secrets/pki: Add Freshest CRL extension (Delta CRL Distribution Points) to base CRLs
BUG FIXES:
* audit/file: The logic preventing setting of executable bits on audit devices was enforced at unseal instead of just at new audit device creation, causing an error at unseal if an existing audit device had exec permissions. The logic now warns and clears exec bits to prevent unseal errors.
* auth/gcp: Fix intermittent context canceled failures for Workload Identity Federation (WIF) authentication
* core (Enterprise): fix unaligned atomic panic in replication code on 32-bit platforms.
* core/managed-keys (enterprise): Fix a bug that prevented the max_parallel field of PKCS#11 managed keys from being updated.
* events (enterprise): Fix missed events when multiple event clients specify the same namespace and event type filters and one client disconnects.
* identity: Repair the integrity of duplicate and/or dangling entity aliases.
* ldap auth (enterprise): Fix root password rotation for Active Directory by implementing UTF-16LE encoding and schema-specific handling. Adds new 'schema' config field (defaults to 'openldap' for backward compatibility).
* secret sync (enterprise): fix panic in set-association API when using Vault Proxy with token-bound CIDRs. The panic occurred due to missing connection information during CIDR validation.
* secret sync (enterprise): fixed panic due to nil pointer dereference when reconciling associations. Added guard checks to prevent access to nil references, making association handling more robust.
* secrets/pki: The root/sign-intermediate endpoint max_path_length parameter is now restricted by the signing CA's max_path_length if set.
* secrets/transit (enterprise): Fix bugs that prevent using ML-DSA and SLH-DSA keys after reading the policy from storage.
## 1.20.9 Enterprise
### March 05, 2026
SECURITY:
* Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* Upgrade `filippo.io/edwards25519` to v1.1.1 to resolve GO-2026-4503
* vault/sdk: Upgrade `cloudflare/circl` to v1.6.3 to resolve CVE-2026-1229
* vault/sdk: Upgrade `go.opentelemetry.io/otel/sdk` to v1.40.0 to resolve GO-2026-4394
CHANGES:
* core: Bump Go version to 1.25.7
* mfa/duo: Upgrade duo_api_golang client to 0.2.0 to include the new Duo certificate authorities
IMPROVEMENTS:
* core/seal: Enhance sys/seal-backend-status to provide more information about seal backends.
* secrets/kmip (Enterprise): Obey configured best_effort_wal_wait_duration when forwarding kmip requests.
* secrets/pki (enterprise): Return the POSTPKIOperation capability within SCEP GetCACaps endpoint for better legacy client support.
BUG FIXES:
* core (enterprise): Buffer the POST body on binary paths to allow re-reading on non-logical forwarding attempts. Addresses an issue for SCEP, EST and CMPv2 certificate issuances with slow replication of entities
* core/identity (enterprise): Fix excessive logging when updating existing aliases
* core/managed-keys (enterprise): client credentials should not be required when using Azure Managed Identities in managed keys.
* plugins (enterprise): Fix bug where requests to external plugins that modify storage weren't populating the X-Vault-Index response header.
* secrets (pki): Allow issuance of certificates without the server_flag key usage from SCEP, EST and CMPV2 protocols.
* secrets/pki (enterprise): Address cache invalidation issues with CMPv2 on performance standby nodes.
* secrets/pki (enterprise): Address issues using SCEP on performance standby nodes failing due to configuration invalidation issues along with errors writing to storage
* secrets/pki (enterprise): Modify the SCEP GetCACaps endpoint to dynamically reflect the configured encryption and digest algorithms.
* secrets/pki: allow glob-style DNS names in alt_names.
* ui: Fixes login form so `?with=<path>` query param correctly displays only the specified mount when multiple mounts of the same auth type are configured with `listing_visibility="unauth"`
## 1.20.8 Enterprise
### February 05, 2026
@ -750,6 +1421,153 @@ intermediate certificates. [[GH-30034](https://github.com/hashicorp/vault/pull/3
* ui: MFA methods now display the namespace path instead of the namespace id. [[GH-29588](https://github.com/hashicorp/vault/pull/29588)]
* ui: Redirect users authenticating with Vault as an OIDC provider to log in again when token expires. [[GH-30838](https://github.com/hashicorp/vault/pull/30838)]
## 1.19.18 Enterprise
### June 05, 2026
BREAKING CHANGES:
* containers: Remove `cap_ipc_lock` capability on `vault` at build time to allow running Vault in common container runtimes. Vault in containers will no longer be able to call `mlock()` to lock memory. Operators should set `disable_mlock = true` in Vault's configuration. Runtime operators are advised to disable swapping to guarantee data safety.
* secrets/ssh: RSA key sizes are now limited to a maximum size of 8192 bits addressing CVE-2026-39829
CHANGES:
* core: Bump Go version to 1.25.11
BUG FIXES:
* plugins: Fix plugin signature verification failure with expired pgp key when registering a plugin.
* ui/transit: Fix key version dropdown selected state when editing a transit key.
## 1.19.17 Enterprise
### May 19, 2026
BREAKING CHANGES:
* containers: set cap_ipc_lock capability on vault at build time. Container runtimes will need to add `IPC_LOCK` capabilities when running the vault container.
SECURITY:
* api: Update golang.org/x/net to resolve GO-2026-4918"
* core/identity: reject wildcards in rendered identity templates
* core: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* core: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* core: Update github.com/apache/thrift to fix security vulnerability GHSA-wf45-q9ch-q8gh
* core: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* core: Update golang.org/x/net to resolve GO-2026-4918"
* core: Validate both `path` and `file_path` cannot be empty for requests to `sys/audit/{path}`
* sdk: Resolve GHSA-j88v-2chj-qfwx by removing our dependency on github.com/jackc/pgx/v3 and github.com/jackc/pgx/v4
* sdk: Update github.com/Azure/go-ntlmssp to fix security vulnerability v0.1.1.
* sdk: Update github.com/jackc/pgx/v5 to fix security vulnerability GHSA-j88v-2chj-qfwx.
* sdk: Update golang.org/x/net to resolve GO-2026-4918"
CHANGES:
* auth/jwt: Update plugin to [v0.23.3](https://github.com/hashicorp/vault-plugin-auth-jwt/releases/tag/v0.23.3)
* core: Bump Go version to 1.25.10
* core: secondary DR requests can now be authenticated using a root token generated on the primary.
* core: sys/generate-root and sys/replication/dr/secondary/generate-operation-token endpoints are now authenticated by default, with the old unauthenticated behaviour enabled by setting the new HCL config key enable_unauthenticated_access to include the value "generate-root" or "generate-operation-token" respectively.
* core: sys/rekey endpoints are now authenticated by default, with the old unauthenticated behaviour enabled by setting the new HCL config key enable_unauthenticated_access to include the value "rekey".
* identity: Require `sudo` capability to invoke the identity entity merge API endpoint (`identity/entity/merge`).
IMPROVEMENTS:
* api: Add migration_done_at_epoch to sys/seal-status response.
* core (Enterprise): Sanitized config now shows kms_library config.
* core/seal (enterprise): Make it possible for new nodes to join a cluster configured with Seal High Availability.
* sdk: Expand support for docker test cluster options like seals, kms libraries, and entropy augmentation. DockerClusterNode.UpdateConfig now takes a full set of cluster options instead of just node config.
BUG FIXES:
* client/ocsp: Adds a grace period to renew the cached entry for OCSP response.
* core: Fix failure to detect errors during storage writes of totp keys.
* database/mssql: Fix "sysadmin" requirement during lease revocation by replacing the undocumented `sp_msloginmappings` procedure with a granular metadata query. This allows the plugin to function with `VIEW ANY DEFINITION` instead of full `sysadmin` privileges.
* database/mssql: Fix dynamic secret revocation by executing custom statements as a single batch instead of splitting on semicolons
* database/snowflake: Fix WAL rollback issue for key-pair root credential rotation.
* database: prevent static role rotation and connection init from hanging indefinitely when database calls block by adding timeouts around UpdateUser and Initialize
* go-plugin: Upgrade go-plugin to fix a bug where file descriptors could be leaked when spawning external plugins
* identity: fixed a rare but possible data race issue with identities.
* plugins/database/hana: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL identifiers before ALTER USER and DROP USER statements.
plugins/database/redshift: Fixed a SQL injection risk in the default DeleteUser revoke path by safely quoting usernames as SQL string literals when invoking terminateloop(...), preventing statement-structure manipulation.
* sdk: Small bugfixes relating to docker test container cleanup and image building.
* secrets/kmip (enterprise): Address a nil pointer within the invalidation handler for managed objects.
* secrets/pki (enterprise): Include root CA in chain for CIEPS endpoints when root is the direct issuer, unless `remove_roots_from_chain` is true.
* ui: Update DR operation token generation to accept a primary root token for authentication.
## 1.19.16 Enterprise
### April 14, 2026
**Enterprise LTS:** Vault Enterprise 1.19 is a [Long-Term Support (LTS)](https://developer.hashicorp.com/vault/docs/enterprise/lts) release.
BREAKING CHANGES:
* sdk/helpers/docker: Migrate docker helpers from github.com/docker/docker to github.com/moby/moby. This was necessary as github.com/docker/docker is no longer maintained. Resolves GHSA-x744-4wpc-v9h2 and GHSA-pxq6-2prw-chj9.
SECURITY:
* api/auth/gcp: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* api/auth: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Correctly remove any Vault tokens from the Authorization header when this header is forwarded to plugin backends. The header will only be forwarded if "Authorization" is explicitly included in the list of passthrough request headers.
* core: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* core: Update github.com/aws/aws-sdk-go-v2/ to fix security vulnerability GHSA-xmrv-pmrh-hhx2.
* core: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
* core: Update github.com/hashicorp/go-getter to fix security vulnerability GHSA-92mm-2pjq-r785.
* core: Update go.opentelemetry.io/otel/sdk to fix CVE-2026-39883.
* core: reject URL-encoded paths that do not specify a canonical path
* sdk: Resolve GO-2026-4518 and GHSA-jqcq-xjh3-6g23 by upgrading to github.com/jackc/pgx/v5
* sdk: Update github.com/go-jose/go-jose to fix security vulnerability CVE-2026-34986 and GHSA-78h2-9frx-2jm8.
CHANGES:
* core: Bump Go version to 1.25.9
* core: Vault now rejects paths that are not canonical, such as paths containing double slashes (`path//to/resource`)
IMPROVEMENTS:
* config/listener: logs warnings on invalid x-forwarded-for configurations.
* dockerfile: container will now run as vault user by default
* pki: Reject obviously unsafe validation targets during ACME HTTP-01 and TLS-ALPN-01 challenge verification
* secrets/pki: Add ACME configuration fields challenge_permitted_ip_ranges and challenge_excluded_ip_ranges configuration to control which IP addresses are allowed or disallowed for challenge validation.
BUG FIXES:
* audit/file: The logic preventing setting of executable bits on audit devices was enforced at unseal instead of just at new audit device creation, causing an error at unseal if an existing audit device had exec permissions. The logic now warns and clears exec bits to prevent unseal errors.
* auth/gcp: Fix intermittent context canceled failures for Workload Identity Federation (WIF) authentication
* core (Enterprise): fix unaligned atomic panic in replication code on 32-bit platforms.
* core/managed-keys (enterprise): Fix a bug that prevented the max_parallel field of PKCS#11 managed keys from being updated.
* events (enterprise): Fix missed events when multiple event clients specify the same namespace and event type filters and one client disconnects.
* identity: Repair the integrity of duplicate and/or dangling entity aliases.
* ldap auth (enterprise): Fix root password rotation for Active Directory by implementing UTF-16LE encoding and schema-specific handling. Adds new 'schema' config field (defaults to 'openldap' for backward compatibility).
* secret sync (enterprise): fix panic in set-association API when using Vault Proxy with token-bound CIDRs. The panic occurred due to missing connection information during CIDR validation.
* secret sync (enterprise): fixed panic due to nil pointer dereference when reconciling associations. Added guard checks to prevent access to nil references, making association handling more robust.
* secrets/pki: The root/sign-intermediate endpoint max_path_length parameter is now restricted by the signing CA's max_path_length if set.
* secrets/transit (enterprise): Fix bugs that prevent using ML-DSA and SLH-DSA keys after reading the policy from storage.
## 1.19.15 Enterprise
### March 05, 2026
SECURITY:
* Upgrade `filippo.io/edwards25519` to v1.1.1 to resolve GO-2026-4503
* vault/sdk: Upgrade `go.opentelemetry.io/otel/sdk` to v1.40.0 to resolve GO-2026-4394
CHANGES:
* core: Bump Go version to 1.25.7
* mfa/duo: Upgrade duo_api_golang client to 0.2.0 to include the new Duo certificate authorities
IMPROVEMENTS:
* core/seal: Enhance sys/seal-backend-status to provide more information about seal backends.
* secrets/kmip (Enterprise): Obey configured best_effort_wal_wait_duration when forwarding kmip requests.
BUG FIXES:
* core (enterprise): Buffer the POST body on binary paths to allow re-reading on non-logical forwarding attempts. Addresses an issue for SCEP, EST and CMPv2 certificate issuances with slow replication of entities
* core/identity (enterprise): Fix excessive logging when updating existing aliases
* core/managed-keys (enterprise): client credentials should not be required when using Azure Managed Identities in managed keys.
* secrets (pki): Allow issuance of certificates without the server_flag key usage from SCEP, EST and CMPV2 protocols.
* secrets/pki (enterprise): Address cache invalidation issues with CMPv2 on performance standby nodes.
* secrets/pki: allow glob-style DNS names in alt_names.
## 1.19.14 Enterprise
### February 05, 2026
@ -2586,7 +3404,26 @@ autopilot to fail to discover new server versions and so not trigger an upgrade.
* ui: fixed a bug where the replication pages did not update display when navigating between DR and performance [[GH-26325](https://github.com/hashicorp/vault/pull/26325)]
* ui: fixes undefined start time in filename for downloaded client count attribution csv [[GH-26485](https://github.com/hashicorp/vault/pull/26485)]
## 1.16.30
## 1.16.31 Enterprise
### March 05, 2026
**Enterprise LTS:** Vault Enterprise 1.16 is a [Long-Term Support (LTS)](https://developer.hashicorp.com/vault/docs/enterprise/lts) release.
SECURITY:
* Upgrade `filippo.io/edwards25519` to v1.1.1 to resolve GO-2026-4503
* vault/sdk: Upgrade `go.opentelemetry.io/otel/sdk` to v1.40.0 to resolve GO-2026-4394
CHANGES:
* core: Bump Go version to 1.24.13
* mfa/duo: Upgrade duo_api_golang client to 0.2.0 to include the new Duo certificate authorities
IMPROVEMENTS:
* core/seal: Enhance sys/seal-backend-status to provide more information about seal backends.
## 1.16.30 Enterprise
### February 05, 2026
**Enterprise LTS:** Vault Enterprise 1.16 is a [Long-Term Support (LTS)](https://developer.hashicorp.com/vault/docs/enterprise/lts) release.

View file

@ -1,182 +1,7 @@
# Copyright IBM Corp. 2016, 2025
# Copyright IBM Corp. 2016, 2026
# SPDX-License-Identifier: BUSL-1.1
## DOCKERHUB DOCKERFILE ##
FROM alpine:3 AS default
ARG BIN_NAME
# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com
# and the version to download. Example: NAME=vault PRODUCT_VERSION=1.2.3.
ARG NAME=vault
ARG PRODUCT_VERSION
ARG PRODUCT_REVISION
# TARGETARCH and TARGETOS are set automatically when --platform is provided.
ARG TARGETOS TARGETARCH
# LICENSE_SOURCE is the path to IBM license documents, which may be architecture-specific.
ARG LICENSE_SOURCE
# LICENSE_DEST is the path where license files are installed in the container
ARG LICENSE_DEST
# Additional metadata labels used by container registries, platforms
# and certification scanners.
LABEL name="Vault" \
maintainer="Vault Team <vault@hashicorp.com>" \
vendor="HashiCorp" \
version=${PRODUCT_VERSION} \
release=${PRODUCT_REVISION} \
revision=${PRODUCT_REVISION} \
summary="Vault is a tool for securely accessing secrets." \
description="Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log."
# Copy the license file as per Legal requirement
COPY ${LICENSE_SOURCE} ${LICENSE_DEST}
# Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD
ENV NAME=$NAME
# Create a non-root user to run the software.
RUN addgroup ${NAME} && adduser -S -G ${NAME} ${NAME}
RUN apk add --no-cache libcap su-exec dumb-init tzdata
COPY dist/$TARGETOS/$TARGETARCH/$BIN_NAME /bin/
# /vault/logs is made available to use as a location to store audit logs, if
# desired; /vault/file is made available to use as a location with the file
# storage backend, if desired; the server will be started with /vault/config as
# the configuration directory so you can add additional config files in that
# location.
RUN mkdir -p /vault/logs && \
mkdir -p /vault/file && \
mkdir -p /vault/config && \
chown -R ${NAME}:${NAME} /vault
# Expose the logs directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/logs
# Expose the file directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/file
# 8200/tcp is the primary interface that applications use to interact with
# Vault.
EXPOSE 8200
# The entry point script uses dumb-init as the top-level process to reap any
# zombie processes created by Vault sub-processes.
#
# For production derivatives of this container, you should add the IPC_LOCK
# capability so that Vault can mlock memory.
COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
# # By default you'll get a single-node development server that stores everything
# # in RAM and bootstraps itself. Don't use this configuration for production.
CMD ["server", "-dev"]
## UBI DOCKERFILE ##
FROM registry.access.redhat.com/ubi10/ubi-minimal AS ubi
ARG BIN_NAME
# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com
# and the version to download. Example: NAME=vault PRODUCT_VERSION=1.2.3.
ARG NAME=vault
ARG PRODUCT_VERSION
ARG PRODUCT_REVISION
# TARGETARCH and TARGETOS are set automatically when --platform is provided.
ARG TARGETOS TARGETARCH
# LICENSE_SOURCE is the path to IBM license documents, which may be architecture-specific.
ARG LICENSE_SOURCE
# LICENSE_DEST is the path where license files are installed in the container
ARG LICENSE_DEST
# Additional metadata labels used by container registries, platforms
# and certification scanners.
LABEL name="Vault" \
maintainer="Vault Team <vault@hashicorp.com>" \
vendor="HashiCorp" \
version=${PRODUCT_VERSION} \
release=${PRODUCT_REVISION} \
revision=${PRODUCT_REVISION} \
summary="Vault is a tool for securely accessing secrets." \
description="Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log."
# Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD
ENV NAME=$NAME
# Copy the license file as per Legal requirement
COPY ${LICENSE_SOURCE} ${LICENSE_DEST}/
# We must have a copy of the license in this directory to comply with the HasLicense Redhat requirement
# Note the trailing slash on the first argument -- plain files meet the requirement but directories do not.
COPY ${LICENSE_SOURCE}/ /licenses/
# Set up certificates, our base tools, and Vault. Unlike the other version of
# this (https://github.com/hashicorp/docker-vault/blob/master/ubi/Dockerfile),
# we copy in the Vault binary from CRT.
RUN set -eux; \
microdnf install -y ca-certificates gnupg openssl libcap tzdata procps shadow-utils util-linux tar
# Create a non-root user to run the software.
RUN groupadd --gid 1000 vault && \
adduser --uid 100 --system -g vault vault && \
usermod -a -G root vault
# Copy in the new Vault from CRT pipeline, rather than fetching it from our
# public releases.
COPY dist/$TARGETOS/$TARGETARCH/$BIN_NAME /bin/
# /vault/logs is made available to use as a location to store audit logs, if
# desired; /vault/file is made available to use as a location with the file
# storage backend, if desired; the server will be started with /vault/config as
# the configuration directory so you can add additional config files in that
# location.
ENV HOME=/home/vault
RUN mkdir -p /vault/logs && \
mkdir -p /vault/file && \
mkdir -p /vault/config && \
mkdir -p $HOME && \
chown -R vault /vault && chown -R vault $HOME && \
chgrp -R 0 $HOME && chmod -R g+rwX $HOME && \
chgrp -R 0 /vault && chmod -R g+rwX /vault
# Expose the logs directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/logs
# Expose the file directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/file
# 8200/tcp is the primary interface that applications use to interact with
# Vault.
EXPOSE 8200
# The entry point script uses dumb-init as the top-level process to reap any
# zombie processes created by Vault sub-processes.
#
# For production derivatives of this container, you should add the IPC_LOCK
# capability so that Vault can mlock memory.
COPY .release/docker/ubi-docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
# Use the Vault user as the default user for starting this container.
USER vault
# # By default you'll get a single-node development server that stores everything
# # in RAM and bootstraps itself. Don't use this configuration for production.
CMD ["server", "-dev"]
FROM ubi AS ubi-fips
FROM ubi AS ubi-hsm
FROM ubi AS ubi-hsm-fips
## Builder:
## Builder
#
# A build container used to build the Vault binary. We use focal because the
# version of glibc is old enough for all of our supported distros for editions
@ -225,3 +50,180 @@ COPY .build/entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# Default
#
# Our default conatiner image.
#
FROM alpine:3 AS default
ARG BIN_NAME
# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com
# and the version to download. Example: NAME=vault PRODUCT_VERSION=1.2.3.
ARG NAME=vault
ARG PRODUCT_VERSION
ARG PRODUCT_REVISION
# TARGETARCH and TARGETOS are set automatically when --platform is provided.
ARG TARGETOS TARGETARCH
# LICENSE_SOURCE is the path to IBM license documents, which may be architecture-specific.
ARG LICENSE_SOURCE
# LICENSE_DEST is the path where license files are installed in the container
ARG LICENSE_DEST
# Additional metadata labels used by container registries, platforms
# and certification scanners.
LABEL name="Vault" \
maintainer="Vault Team <vault@hashicorp.com>" \
vendor="HashiCorp" \
version=${PRODUCT_VERSION} \
release=${PRODUCT_REVISION} \
revision=${PRODUCT_REVISION} \
summary="Vault is a tool for securely accessing secrets." \
description="Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log."
# Copy the license file as per Legal requirement
COPY ${LICENSE_SOURCE} ${LICENSE_DEST}
# Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD
ENV NAME=$NAME
# Create a non-root user to run the software.
RUN addgroup ${NAME} && adduser -S -G ${NAME} ${NAME}
# NOTE: zlib is only here to resolve ALPINE-CVE-2026-27171, it can be removed
# when when our Alpine release is >= 3.23.4
RUN apk update && apk add --upgrade --no-cache su-exec dumb-init tzdata zlib
COPY dist/$TARGETOS/$TARGETARCH/${BIN_NAME} /bin/${BIN_NAME}
# /vault/logs is made available to use as a location to store audit logs, if
# desired; /vault/file is made available to use as a location with the file
# storage backend, if desired; the server will be started with /vault/config as
# the configuration directory so you can add additional config files in that
# location.
RUN mkdir -p /vault/logs && \
mkdir -p /vault/file && \
mkdir -p /vault/config && \
chown -R ${NAME}:${NAME} /vault
# Expose the logs directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/logs
# Expose the file directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/file
# 8200/tcp is the primary interface that applications use to interact with
# Vault.
EXPOSE 8200
# The entry point script uses dumb-init as the top-level process to reap any
# zombie processes created by Vault sub-processes.
#
# For production derivatives of this container, you should add the IPC_LOCK
# capability so that Vault can mlock memory.
COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
# Use the Vault user as the default user for starting this container.
USER ${NAME}
# # By default you'll get a single-node development server that stores everything
# # in RAM and bootstraps itself. Don't use this configuration for production.
CMD ["server", "-dev"]
# UBI
#
# Our UBI container image
#
FROM registry.access.redhat.com/ubi10/ubi-minimal AS ubi
ARG BIN_NAME
# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com
# and the version to download. Example: NAME=vault PRODUCT_VERSION=1.2.3.
ARG NAME=vault
ARG PRODUCT_VERSION
ARG PRODUCT_REVISION
# TARGETARCH and TARGETOS are set automatically when --platform is provided.
ARG TARGETOS TARGETARCH
# LICENSE_SOURCE is the path to IBM license documents, which may be architecture-specific.
ARG LICENSE_SOURCE
# LICENSE_DEST is the path where license files are installed in the container
ARG LICENSE_DEST
# Additional metadata labels used by container registries, platforms
# and certification scanners.
LABEL name="Vault" \
maintainer="Vault Team <vault@hashicorp.com>" \
vendor="HashiCorp" \
version=${PRODUCT_VERSION} \
release=${PRODUCT_REVISION} \
revision=${PRODUCT_REVISION} \
summary="Vault is a tool for securely accessing secrets." \
description="Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log."
# Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD
ENV NAME=$NAME
# Copy the license file as per Legal requirement
COPY ${LICENSE_SOURCE} ${LICENSE_DEST}/
# We must have a copy of the license in this directory to comply with the HasLicense Redhat requirement
# Note the trailing slash on the first argument -- plain files meet the requirement but directories do not.
COPY ${LICENSE_SOURCE}/ /licenses/
# Set up certificates, our base tools, and Vault. Unlike the other version of
# this (https://github.com/hashicorp/docker-vault/blob/master/ubi/Dockerfile),
# we copy in the Vault binary from CRT.
RUN set -eux; \
microdnf install -y ca-certificates gnupg openssl tzdata procps shadow-utils util-linux tar
# Create a non-root user to run the software.
RUN groupadd --gid 1000 vault && \
adduser --uid 100 --system -g vault vault && \
usermod -a -G root vault
COPY dist/$TARGETOS/$TARGETARCH/${BIN_NAME} /bin/${BIN_NAME}
# /vault/logs is made available to use as a location to store audit logs, if
# desired; /vault/file is made available to use as a location with the file
# storage backend, if desired; the server will be started with /vault/config as
# the configuration directory so you can add additional config files in that
# location.
ENV HOME=/home/vault
RUN mkdir -p /vault/logs && \
mkdir -p /vault/file && \
mkdir -p /vault/config && \
mkdir -p $HOME && \
chown -R vault /vault && chown -R vault $HOME && \
chgrp -R 0 $HOME && chmod -R g+rwX $HOME && \
chgrp -R 0 /vault && chmod -R g+rwX /vault
# Expose the logs directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/logs
# Expose the file directory as a volume since there's potentially long-running
# state in there
VOLUME /vault/file
# 8200/tcp is the primary interface that applications use to interact with
# Vault.
EXPOSE 8200
# The entry point script uses dumb-init as the top-level process to reap any
# zombie processes created by Vault sub-processes.
#
# For production derivatives of this container, you should add the IPC_LOCK
# capability so that Vault can mlock memory.
COPY .release/docker/ubi-docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
# Use the Vault user as the default user for starting this container.
USER ${NAME}
# # By default you'll get a single-node development server that stores everything
# # in RAM and bootstraps itself. Don't use this configuration for production.
CMD ["server", "-dev"]

14
LICENSE
View file

@ -3,22 +3,22 @@ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
Parameters
Licensor: HashiCorp, Inc.
Licensor: International Business Machines Corporation (IBM)
Licensed Work: Vault Version 1.15.0 or later. The Licensed Work is (c) 2024
HashiCorp, Inc.
IBM Corp.
Additional Use Grant: You may make production use of the Licensed Work, provided
Your use does not include offering the Licensed Work to third
parties on a hosted or embedded basis in order to compete with
HashiCorp's paid version(s) of the Licensed Work. For purposes
IBM Corp's paid version(s) of the Licensed Work. For purposes
of this license:
A "competitive offering" is a Product that is offered to third
parties on a paid basis, including through paid support
arrangements, that significantly overlaps with the capabilities
of HashiCorp's paid version(s) of the Licensed Work. If Your
of IBM Corp's paid version(s) of the Licensed Work. If Your
Product is not a competitive offering when You first make it
generally available, it will not become a competitive offering
later due to HashiCorp releasing a new version of the Licensed
later due to IBM Corp releasing a new version of the Licensed
Work with additional capabilities. In addition, Products that
are not provided on a paid basis are not competitive.
@ -34,10 +34,10 @@ Additional Use Grant: You may make production use of the Licensed Work, provided
Hosting or using the Licensed Work(s) for internal purposes
within an organization is not considered a competitive
offering. HashiCorp considers your organization to include all
offering. IBM Corp considers your organization to include all
of your affiliates under common control.
For binding interpretive guidance on using HashiCorp products
For binding interpretive guidance on using IBM Corp products
under the Business Source License, please visit our FAQ.
(https://www.hashicorp.com/license-faq)
Change Date: Four years from the date the Licensed Work is published.

View file

@ -13,6 +13,13 @@ INTEG_TEST_TIMEOUT=120m
VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods -nilfunc -printf -rangeloops -shift -structtags -unsafeptr
GOFMT_FILES?=$$(find . -name '*.go' | grep -v pb.go | grep -v vendor)
SED?=$(shell command -v gsed || command -v sed)
SED_CMD := $(SED) -i
# MacOS without gsed requires an empty string argument for -i.
ifeq ($(shell uname -s),Darwin)
ifneq ($(findstring gsed,$(SED)),gsed)
SED_CMD := $(SED) -i ''
endif
endif
GO_VERSION_MIN=$$(cat $(CURDIR)/.go-version)
GO_CMD?=go
@ -163,18 +170,24 @@ protolint: prep check-tools-external
@echo "==> Linting protobufs..."
@buf lint
# prep runs `go generate` to build the dynamically generated
# source files.
# prep runs `go generate` to build the dynamically generated source files.
# Since generated files are committed to git, this is usually not needed.
# Set SKIP_GEN=1 to skip generation (for savvy users who know they don't need it).
#
# n.b.: prep used to depend on fmtcheck, but since fmtcheck is
# now run as a pre-commit hook (and there's little value in
# making every build run the formatter), we've removed that
# dependency.
prep: check-go-version clean
@echo "==> Running go generate..."
@GOARCH= GOOS= $(GO_CMD) generate $(MAIN_PACKAGES)
@GOARCH= GOOS= cd api && $(GO_CMD) generate $(API_PACKAGES)
@GOARCH= GOOS= cd sdk && $(GO_CMD) generate $(SDK_PACKAGES)
prep: check-go-version
@if [ "$(SKIP_GEN)" = "1" ]; then \
echo "==> Skipping go generate (SKIP_GEN=1)"; \
else \
$(MAKE) clean; \
echo "==> Running go generate..."; \
GOARCH= GOOS= $(GO_CMD) generate $(MAIN_PACKAGES); \
(cd api && GOARCH= GOOS= $(GO_CMD) generate $(API_PACKAGES)); \
(cd sdk && GOARCH= GOOS= $(GO_CMD) generate $(SDK_PACKAGES)); \
fi
# Git doesn't allow us to store shared hooks in .git. Instead, we make sure they're up-to-date
# whenever a make target is invoked.
@ -229,18 +242,18 @@ proto: check-tools-external
# No additional sed expressions should be added to this list. Going forward
# we should just use the variable names chosen by protobuf. These are left
# here for backwards compatibility, namely for SDK compilation.
$(SED) -i -e 's/Id/ID/' -e 's/SPDX-License-IDentifier/SPDX-License-Identifier/' vault/request_forwarding_service.pb.go
$(SED) -i -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/IDentity/Identity/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/Totp/TOTP/' -e 's/Mfa/MFA/' -e 's/Pingid/PingID/' -e 's/namespaceId/namespaceID/' -e 's/Ttl/TTL/' -e 's/BoundCidrs/BoundCIDRs/' -e 's/SPDX-License-IDentifier/SPDX-License-Identifier/' helper/identity/types.pb.go helper/identity/mfa/types.pb.go helper/storagepacker/types.pb.go sdk/plugin/pb/backend.pb.go sdk/logical/identity.pb.go vault/activity/activity_log.pb.go
$(SED_CMD) -e 's/Id/ID/' -e 's/SPDX-License-IDentifier/SPDX-License-Identifier/' vault/request_forwarding_service.pb.go
$(SED_CMD) -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/IDentity/Identity/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/Totp/TOTP/' -e 's/Mfa/MFA/' -e 's/Pingid/PingID/' -e 's/namespaceId/namespaceID/' -e 's/Ttl/TTL/' -e 's/BoundCidrs/BoundCIDRs/' -e 's/SPDX-License-IDentifier/SPDX-License-Identifier/' helper/identity/types.pb.go helper/identity/mfa/types.pb.go helper/storagepacker/types.pb.go sdk/plugin/pb/backend.pb.go sdk/logical/identity.pb.go vault/activity/activity_log.pb.go
# This will inject the sentinel struct tags as decorated in the proto files.
protoc-go-inject-tag -input=./helper/identity/types.pb.go
protoc-go-inject-tag -input=./helper/identity/mfa/types.pb.go
importfmt: check-tools-external
find . -name '*.go' | grep -v pb.go | grep -v vendor | xargs gosimports -w
find . -name '*.go' -not -path './.git/*' | grep -v pb.go | grep -v vendor | xargs gosimports -w
fmt: importfmt
find . -name '*.go' | grep -v pb.go | grep -v vendor | xargs gofumpt -w
find . -name '*.go' -not -path './.git/*' | grep -v pb.go | grep -v vendor | xargs gofumpt -w
fmtcheck: check-go-fmt

View file

@ -201,7 +201,6 @@ func Test_Something_With_Docker(t *testing.T) {
ImageTag: "latest",
}
cluster := docker.NewTestDockerCluster(t, opts)
defer cluster.Cleanup()
client := cluster.Nodes()[0].APIClient()
_, err := client.Logical().Read("sys/storage/raft/configuration")
@ -226,7 +225,6 @@ func Test_Something_With_Docker(t *testing.T) {
VaultLicense: licenseString, // not a path, the actual license bytes
}
cluster := docker.NewTestDockerCluster(t, opts)
defer cluster.Cleanup()
}
```
@ -245,7 +243,6 @@ build as a debugging convenience.
func Test_Custom_Build_With_Docker(t *testing.T) {
opts := docker.DefaultOptions(t)
cluster := docker.NewTestDockerCluster(t, opts)
defer cluster.Cleanup()
}
```

View file

@ -1,12 +1,12 @@
module github.com/hashicorp/vault/api/auth/approle
go 1.24.0
go 1.25.0
require github.com/hashicorp/vault/api v1.22.0
require github.com/hashicorp/vault/api v1.23.0
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -19,8 +19,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,19 +1,19 @@
module github.com/hashicorp/vault/api/auth/aws
go 1.24.0
go 1.25.0
require (
github.com/aws/aws-sdk-go v1.55.7
github.com/hashicorp/go-hclog v1.6.3
github.com/hashicorp/go-secure-stdlib/awsutil v0.3.0
github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/vault/api v1.22.0
github.com/hashicorp/vault/api v1.23.0
)
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -30,9 +30,8 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -10,8 +10,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
@ -41,8 +41,8 @@ github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2I
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
@ -83,11 +83,9 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -95,11 +93,11 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -1,12 +1,12 @@
module github.com/hashicorp/vault/api/auth/azure
go 1.24.0
go 1.25.0
require github.com/hashicorp/vault/api v1.22.0
require github.com/hashicorp/vault/api v1.23.0
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -19,8 +19,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,15 +1,15 @@
module github.com/hashicorp/vault/api/auth/cert
go 1.24.0
go 1.25.0
require (
github.com/hashicorp/go-rootcerts v1.0.2
github.com/hashicorp/vault/api v1.22.0
github.com/hashicorp/vault/api v1.23.0
)
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -21,8 +21,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,11 +1,11 @@
module github.com/hashicorp/vault/api/auth/gcp
go 1.24.0
go 1.25.0
require (
cloud.google.com/go/compute/metadata v0.7.0
cloud.google.com/go/compute/metadata v0.9.0
cloud.google.com/go/iam v1.5.2
github.com/hashicorp/vault/api v1.22.0
github.com/hashicorp/vault/api v1.23.0
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2
)
@ -13,9 +13,10 @@ require (
cloud.google.com/go/auth v0.16.2 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
@ -32,22 +33,24 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
go.opentelemetry.io/otel v1.43.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/otel/sdk v1.43.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/api v0.242.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/grpc v1.79.3 // indirect
google.golang.org/protobuf v1.36.10 // indirect
)

View file

@ -2,23 +2,32 @@ cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4=
cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=
github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
@ -56,8 +65,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -66,53 +75,57 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg=
google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50=
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,12 +1,12 @@
module github.com/hashicorp/vault/api/auth/kubernetes
go 1.24.0
go 1.25.0
require github.com/hashicorp/vault/api v1.22.0
require github.com/hashicorp/vault/api v1.23.0
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -19,8 +19,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,12 +1,12 @@
module github.com/hashicorp/vault/api/auth/ldap
go 1.24.0
go 1.25.0
require github.com/hashicorp/vault/api v1.22.0
require github.com/hashicorp/vault/api v1.23.0
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -19,8 +19,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,12 +1,12 @@
module github.com/hashicorp/vault/api/auth/userpass
go 1.24.0
go 1.25.0
require github.com/hashicorp/vault/api v1.22.0
require github.com/hashicorp/vault/api v1.23.0
require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -19,8 +19,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.12.0 // indirect
)

View file

@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -29,8 +29,8 @@ github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0=
github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@ -45,14 +45,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -5,11 +5,11 @@ module github.com/hashicorp/vault/api
// automatically track the Go version used to build Vault itself. Many projects import
// the api module and we don't want to impose a newer version on them any more than we
// have to.
go 1.24.0
go 1.25.0
require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/go-jose/go-jose/v4 v4.1.1
github.com/go-jose/go-jose/v4 v4.1.4
github.com/go-test/deep v1.1.1
github.com/hashicorp/errwrap v1.1.0
github.com/hashicorp/go-cleanhttp v0.5.2
@ -24,7 +24,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/natefinch/atomic v1.0.1
github.com/stretchr/testify v1.10.0
golang.org/x/net v0.47.0
golang.org/x/net v0.55.0
golang.org/x/time v0.12.0
)
@ -36,8 +36,7 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View file

@ -6,8 +6,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -53,20 +53,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

View file

@ -393,6 +393,15 @@ func (c *Logical) DeleteWithContext(ctx context.Context, path string) (*Secret,
return c.DeleteWithDataWithContext(ctx, path, nil)
}
func (c *Logical) DeleteRaw(path string) (*Response, error) {
return c.DeleteRawWithContext(context.Background(), path)
}
func (c *Logical) DeleteRawWithContext(ctx context.Context, path string) (*Response, error) {
r := c.c.NewRequest(http.MethodDelete, "/v1/"+path)
return c.c.RawRequestWithContext(ctx, r)
}
func (c *Logical) DeleteWithData(path string, data map[string][]string) (*Secret, error) {
return c.DeleteWithDataWithContext(context.Background(), path, data)
}

View file

@ -22,6 +22,7 @@ var sudoPaths = map[string]*regexp.Regexp{
"/sys/audit/{path}": regexp.MustCompile(`^/sys/audit/.+$`),
"/sys/auth/{path}": regexp.MustCompile(`^/sys/auth/.+$`),
"/sys/auth/{path}/tune": regexp.MustCompile(`^/sys/auth/.+/tune$`),
"/sys/mounts/auth/{path}/tune": regexp.MustCompile(`^/sys/mounts/auth/.+/tune$`),
"/sys/config/auditing/request-headers": regexp.MustCompile(`^/sys/config/auditing/request-headers$`),
"/sys/config/auditing/request-headers/{header}": regexp.MustCompile(`^/sys/config/auditing/request-headers/.+$`),
"/sys/config/cors": regexp.MustCompile(`^/sys/config/cors$`),
@ -48,6 +49,7 @@ var sudoPaths = map[string]*regexp.Regexp{
"/sys/rotate": regexp.MustCompile(`^/sys/rotate$`),
"/sys/seal": regexp.MustCompile(`^/sys/seal$`),
"/sys/step-down": regexp.MustCompile(`^/sys/step-down$`),
"/identity/entity/merge": regexp.MustCompile(`^/identity/entity/merge/?$`),
// enterprise-only paths
"/sys/replication/dr/primary/secondary-token": regexp.MustCompile(`^/sys/replication/dr/primary/secondary-token$`),
@ -57,6 +59,14 @@ var sudoPaths = map[string]*regexp.Regexp{
"/sys/storage/raft/snapshot-auto/config": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/?$`),
"/sys/storage/raft/snapshot-auto/config/{name}": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/[^/]+$`),
"/sys/reporting/scan": regexp.MustCompile(`^/sys/reporting/scan$`),
// activation-flags paths requiring sudo
"/sys/activation-flags/oauth-resource-server/activate": regexp.MustCompile(`^/sys/activation-flags/oauth-resource-server/activate$`),
"/sys/activation-flags/oauth-resource-server/deactivate": regexp.MustCompile(`^/sys/activation-flags/oauth-resource-server/deactivate$`),
// OAuth resource server profile paths requiring sudo
"/sys/config/oauth-resource-server/{name}": regexp.MustCompile(`^/sys/config/oauth-resource-server/[^/]+$`),
"/sys/config/oauth-resource-server": regexp.MustCompile(`^/sys/config/oauth-resource-server$`),
}
func SudoPaths() map[string]*regexp.Regexp {

View file

@ -68,3 +68,71 @@ type UsageMetric struct {
MetricName string `json:"metric_name" mapstructure:"metric_name"`
MetricData map[string]interface{} `json:"metric_data" mapstructure:"metric_data"`
}
// GetBillingConfig returns the current billing retention configuration.
func (c *Sys) GetBillingConfig() (*BillingConfigResponse, error) {
return c.GetBillingConfigWithContext(context.Background())
}
// GetBillingConfigWithContext returns the current billing retention configuration.
func (c *Sys) GetBillingConfigWithContext(ctx context.Context) (*BillingConfigResponse, error) {
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
defer cancelFunc()
r := c.c.NewRequest(http.MethodGet, "/v1/sys/billing/config")
resp, err := c.c.rawRequestWithContext(ctx, r)
if err != nil {
return nil, err
}
defer resp.Body.Close()
secret, err := ParseSecret(resp.Body)
if err != nil {
return nil, err
}
if secret == nil || secret.Data == nil {
return nil, errors.New("data from server response is empty")
}
var result BillingConfigResponse
err = mapstructure.Decode(secret.Data, &result)
if err != nil {
return nil, err
}
return &result, nil
}
// SetBillingConfig sets the billing retention configuration.
func (c *Sys) SetBillingConfig(retentionMonths int) error {
return c.SetBillingConfigWithContext(context.Background(), retentionMonths)
}
// SetBillingConfigWithContext sets the billing retention configuration.
func (c *Sys) SetBillingConfigWithContext(ctx context.Context, retentionMonths int) error {
ctx, cancelFunc := c.c.withConfiguredTimeout(ctx)
defer cancelFunc()
body := map[string]interface{}{
"retention_months": retentionMonths,
}
r := c.c.NewRequest(http.MethodPost, "/v1/sys/billing/config")
if err := r.SetJSONBody(body); err != nil {
return err
}
resp, err := c.c.rawRequestWithContext(ctx, r)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
// BillingConfigResponse represents the response from the billing config endpoint.
type BillingConfigResponse struct {
RetentionMonths int `json:"retention_months" mapstructure:"retention_months"`
}

View file

@ -33,32 +33,46 @@ func TestSys_BillingOverview(t *testing.T) {
currentMonth := resp.Months[0]
require.Equal(t, "2026-01", currentMonth.Month)
require.Equal(t, "2026-01-14T10:49:00Z", currentMonth.UpdatedAt)
require.Len(t, currentMonth.UsageMetrics, 4)
require.Len(t, currentMonth.UsageMetrics, 9, "should have all 9 metrics")
// Verify static_secrets metric
staticSecretsMetric := currentMonth.UsageMetrics[0]
require.Equal(t, "static_secrets", staticSecretsMetric.MetricName)
require.NotNil(t, staticSecretsMetric.MetricData)
// Create a map to verify all expected metrics are present
metricsMap := make(map[string]UsageMetric)
for _, metric := range currentMonth.UsageMetrics {
metricsMap[metric.MetricName] = metric
}
// Verify all expected metrics are present
expectedMetrics := []string{
"static_secrets",
"dynamic_roles",
"auto_rotated_roles",
"kmip",
"external_plugins",
"data_protection_calls",
"pki_units",
"managed_keys",
"ssh_units",
}
for _, metricName := range expectedMetrics {
metric, exists := metricsMap[metricName]
require.True(t, exists, "metric %s should be present", metricName)
require.NotNil(t, metric.MetricData, "metric_data should not be nil for %s", metricName)
}
// Verify specific metric structures
staticSecretsMetric := metricsMap["static_secrets"]
require.Contains(t, staticSecretsMetric.MetricData, "total")
require.Contains(t, staticSecretsMetric.MetricData, "metric_details")
// Verify kmip metric
kmipMetric := currentMonth.UsageMetrics[1]
require.Equal(t, "kmip", kmipMetric.MetricName)
require.NotNil(t, kmipMetric.MetricData)
kmipMetric := metricsMap["kmip"]
require.Contains(t, kmipMetric.MetricData, "used_in_month")
require.Equal(t, true, kmipMetric.MetricData["used_in_month"])
// Verify pki_units metric
pkiMetric := currentMonth.UsageMetrics[2]
require.Equal(t, "pki_units", pkiMetric.MetricName)
require.NotNil(t, pkiMetric.MetricData)
pkiMetric := metricsMap["pki_units"]
require.Contains(t, pkiMetric.MetricData, "total")
// Verify managed_keys metric
managedKeysMetric := currentMonth.UsageMetrics[3]
require.Equal(t, "managed_keys", managedKeysMetric.MetricName)
require.NotNil(t, managedKeysMetric.MetricData)
managedKeysMetric := metricsMap["managed_keys"]
require.Contains(t, managedKeysMetric.MetricData, "total")
require.Contains(t, managedKeysMetric.MetricData, "metric_details")
@ -73,6 +87,10 @@ func TestSys_BillingOverview(t *testing.T) {
require.Equal(t, "external_plugins", externalPluginsMetric.MetricName)
require.NotNil(t, externalPluginsMetric.MetricData)
require.Contains(t, externalPluginsMetric.MetricData, "total")
sshMetric := metricsMap["ssh_units"]
require.Contains(t, sshMetric.MetricData, "total")
require.Contains(t, sshMetric.MetricData, "metric_details")
}
func mockVaultBillingHandler(w http.ResponseWriter, _ *http.Request) {
@ -102,12 +120,78 @@ const billingOverviewResponse = `{
]
}
},
{
"metric_name": "dynamic_roles",
"metric_data": {
"total": 15,
"metric_details": [
{
"type": "aws_dynamic",
"count": 5
},
{
"type": "azure_dynamic",
"count": 5
},
{
"type": "database_dynamic",
"count": 5
}
]
}
},
{
"metric_name": "auto_rotated_roles",
"metric_data": {
"total": 15,
"metric_details": [
{
"type": "aws_static",
"count": 5
},
{
"type": "azure_static",
"count": 5
},
{
"type": "os_local_account_static",
"count": 5
}
]
}
},
{
"metric_name": "kmip",
"metric_data": {
"used_in_month": true
}
},
{
"metric_name": "external_plugins",
"metric_data": {
"total": 3
}
},
{
"metric_name": "data_protection_calls",
"metric_data": {
"total": 100,
"metric_details": [
{
"type": "transit",
"count": 50
},
{
"type": "transform",
"count": 50
},
{
"type": "gcpkms",
"count": 50
}
]
}
},
{
"metric_name": "pki_units",
"metric_data": {
@ -123,12 +207,28 @@ const billingOverviewResponse = `{
"type": "totp",
"count": 5
},
{
"type": "kmse",
"count": 5
}
{
"type": "kmse",
"count": 5
}
]
}
},
{
"metric_name": "ssh_units",
"metric_data": {
"total": 8.4,
"metric_details": [
{
"type": "otp_units",
"count": 5
},
{
"type": "certificate_units",
"count": 3.4
}
]
}
}
]
},
@ -150,3 +250,46 @@ const billingOverviewResponse = `{
"warnings": null,
"auth": null
}`
// TestSys_BillingConfig tests the GetBillingConfig and SetBillingConfig API client methods
func TestSys_BillingConfig(t *testing.T) {
mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultBillingConfigHandler))
defer mockVaultServer.Close()
// Create API client pointing to mock server
cfg := DefaultConfig()
cfg.Address = mockVaultServer.URL
client, err := NewClient(cfg)
require.NoError(t, err)
// Test GetBillingConfig
resp, err := client.Sys().GetBillingConfig()
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, 37, resp.RetentionMonths)
// Test SetBillingConfig
err = client.Sys().SetBillingConfig(48)
require.NoError(t, err)
}
func mockVaultBillingConfigHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
_, _ = w.Write([]byte(billingConfigResponse))
} else if r.Method == http.MethodPost {
w.WriteHeader(http.StatusNoContent)
}
}
const billingConfigResponse = `{
"request_id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"retention_months": 37
},
"wrap_info": null,
"warnings": null,
"auth": null
}`

View file

@ -96,25 +96,26 @@ func sealStatusRequestWithContext(ctx context.Context, c *Sys, r *Request) (*Sea
}
type SealStatusResponse struct {
Type string `json:"type"`
Initialized bool `json:"initialized"`
Sealed bool `json:"sealed"`
T int `json:"t"`
N int `json:"n"`
Progress int `json:"progress"`
Nonce string `json:"nonce"`
Version string `json:"version"`
BuildDate string `json:"build_date"`
Migration bool `json:"migration"`
ClusterName string `json:"cluster_name,omitempty"`
ClusterID string `json:"cluster_id,omitempty"`
RecoverySeal bool `json:"recovery_seal"`
RecoverySealType string `json:"recovery_seal_type,omitempty"`
StorageType string `json:"storage_type,omitempty"`
HCPLinkStatus string `json:"hcp_link_status,omitempty"`
HCPLinkResourceID string `json:"hcp_link_resource_ID,omitempty"`
RemovedFromCluster *bool `json:"removed_from_cluster,omitempty"`
Warnings []string `json:"warnings,omitempty"`
Type string `json:"type"`
Initialized bool `json:"initialized"`
Sealed bool `json:"sealed"`
T int `json:"t"`
N int `json:"n"`
Progress int `json:"progress"`
Nonce string `json:"nonce"`
Version string `json:"version"`
BuildDate string `json:"build_date"`
Migration bool `json:"migration"`
ClusterName string `json:"cluster_name,omitempty"`
ClusterID string `json:"cluster_id,omitempty"`
RecoverySeal bool `json:"recovery_seal"`
RecoverySealType string `json:"recovery_seal_type,omitempty"`
StorageType string `json:"storage_type,omitempty"`
HCPLinkStatus string `json:"hcp_link_status,omitempty"`
HCPLinkResourceID string `json:"hcp_link_resource_ID,omitempty"`
RemovedFromCluster *bool `json:"removed_from_cluster,omitempty"`
Warnings []string `json:"warnings,omitempty"`
MigrationDoneAtEpoch int64 `json:"migration_done_at_epoch,omitempty"`
}
type UnsealOpts struct {

View file

@ -5,6 +5,7 @@ package audit
import (
"context"
"encoding/json"
"errors"
"fmt"
"maps"
@ -253,6 +254,50 @@ func clone[V any](s V) (V, error) {
return s2.(V), err
}
// mergeEnterpriseTokenMetadata injects enterprise token fields from a logical.Request
// into the audit auth's Metadata map.
func mergeEnterpriseTokenMetadata(a *auth, req *logical.Request) error {
if a == nil || req == nil {
return nil
}
if req.EnterpriseTokenMetadata == "" &&
req.EnterpriseTokenIssuer == "" &&
req.EnterpriseTokenTransaction == "" &&
len(req.EnterpriseTokenAudience) == 0 &&
len(req.EnterpriseTokenAuthorizationDetails) == 0 {
return nil
}
if a.Metadata == nil {
a.Metadata = make(map[string]string)
}
if req.EnterpriseTokenMetadata != "" {
a.Metadata["enterprise_token_metadata"] = req.EnterpriseTokenMetadata
}
if req.EnterpriseTokenIssuer != "" {
a.Metadata["enterprise_token_issuer"] = req.EnterpriseTokenIssuer
}
if req.EnterpriseTokenTransaction != "" {
a.Metadata["enterprise_token_transaction"] = req.EnterpriseTokenTransaction
}
if len(req.EnterpriseTokenAudience) > 0 {
audJSON, err := json.Marshal(req.EnterpriseTokenAudience)
if err != nil {
return fmt.Errorf("unable to marshal enterprise token audience for audit: %w", err)
}
a.Metadata["enterprise_token_audience"] = string(audJSON)
}
if len(req.EnterpriseTokenAuthorizationDetails) > 0 {
authzJSON, err := json.Marshal(req.EnterpriseTokenAuthorizationDetails)
if err != nil {
return fmt.Errorf("unable to marshal enterprise token authorization details for audit: %w", err)
}
a.Metadata["enterprise_token_authorization_details"] = string(authzJSON)
}
return nil
}
// newAuth takes a logical.Auth and the number of remaining client token uses
// (which should be supplied from the logical.Request's client token), and creates
// an audit auth.
@ -281,6 +326,18 @@ func newAuth(input *logical.Auth, tokenRemainingUses int) (*auth, error) {
return nil, fmt.Errorf("unable to clone logical auth: metadata: %w", err)
}
if input.ActorEntityID != "" || input.ActorEntityName != "" {
if metadata == nil {
metadata = make(map[string]string)
}
if input.ActorEntityID != "" {
metadata["actor_entity_id"] = input.ActorEntityID
}
if input.ActorEntityName != "" {
metadata["actor_entity_name"] = input.ActorEntityName
}
}
policies, err := clone(input.Policies)
if err != nil {
return nil, fmt.Errorf("unable to clone logical auth: policies: %w", err)
@ -535,6 +592,10 @@ func (f *entryFormatter) createEntry(ctx context.Context, a *Event) (*entry, err
return nil, fmt.Errorf("cannot convert auth: %w", err)
}
if err := mergeEnterpriseTokenMetadata(auth, data.Request); err != nil {
return nil, err
}
req, err := newRequest(data.Request, ns)
if err != nil {
return nil, fmt.Errorf("cannot convert request: %w", err)
@ -548,6 +609,12 @@ func (f *entryFormatter) createEntry(ctx context.Context, a *Event) (*entry, err
return nil, fmt.Errorf("cannot convert response: %w", err)
}
if resp != nil && resp.Auth != nil {
if err := mergeEnterpriseTokenMetadata(resp.Auth, data.Request); err != nil {
return nil, err
}
}
// If the plugin's response contained any additional audit request fields,
// lets populate them on our original request.
if data.Response != nil && data.Response.SupplementalAuditRequestData != nil {

View file

@ -26,8 +26,7 @@ import (
"github.com/stretchr/testify/require"
)
const testFormatJSONReqBasicStrFmt = `
{
const testFormatJSONReqBasicStrFmt = `{
"time": "2015-08-05T13:45:46Z",
"type": "request",
"auth": {
@ -60,6 +59,43 @@ const testFormatJSONReqBasicStrFmt = `
}
`
const testFormatJSONEnterpriseTokenStrFmt = `{
"time": "2015-08-05T13:45:46Z",
"type": "request",
"auth": {
"client_token": "%s",
"accessor": "bar",
"display_name": "testtoken",
"policies": [
"root"
],
"no_default_policy": true,
"metadata": {
"actor_entity_id": "actor-entity-789",
"actor_entity_name": "actor-service",
"enterprise_token_metadata": "test-token-123"
},
"entity_id": "foobarentity",
"token_type": "service",
"token_ttl": 14400,
"token_issue_time": "2020-05-28T13:40:18-05:00"
},
"request": {
"operation": "update",
"path": "/foo",
"data": null,
"wrap_ttl": 60,
"remote_address": "127.0.0.1",
"headers": {
"foo": [
"bar"
]
}
},
"error": "this is an error"
}
`
// testHeaderFormatter is a stub to prevent the need to import the vault package
// to bring in vault.HeadersConfig for testing.
type testHeaderFormatter struct {
@ -495,6 +531,461 @@ func BenchmarkAuditFileSink_Process(b *testing.B) {
})
}
// TestEntryFormatter_ActorAuth ensures that actor entity fields and EnterpriseToken*
// fields are correctly mapped into auth metadata from logical.Auth and logical.Request.
func TestEntryFormatter_ActorAuth(t *testing.T) {
t.Parallel()
authTests := map[string]struct {
Input *logical.Auth
ExpectedActorEntityID string
ExpectedActorEntityName string
}{
"actor-fields-present": {
Input: &logical.Auth{
EntityID: "subject-123",
DisplayName: "subject-user",
ActorEntityID: "actor-456",
ActorEntityName: "actor-service",
TokenType: logical.TokenTypeDefault,
},
ExpectedActorEntityID: "actor-456",
ExpectedActorEntityName: "actor-service",
},
"actor-fields-absent": {
Input: &logical.Auth{
EntityID: "subject-123",
DisplayName: "subject-user",
TokenType: logical.TokenTypeDefault,
},
},
}
for name, tc := range authTests {
t.Run(name, func(t *testing.T) {
t.Parallel()
result, err := newAuth(tc.Input, 0)
require.NoError(t, err)
require.NotNil(t, result)
if tc.ExpectedActorEntityID != "" {
got, ok := result.Metadata["actor_entity_id"]
require.True(t, ok, "actor_entity_id should be present in auth metadata")
require.Equal(t, tc.ExpectedActorEntityID, got)
} else {
_, ok := result.Metadata["actor_entity_id"]
require.False(t, ok, "actor_entity_id should be absent in auth metadata")
}
if tc.ExpectedActorEntityName != "" {
got, ok := result.Metadata["actor_entity_name"]
require.True(t, ok, "actor_entity_name should be present in auth metadata")
require.Equal(t, tc.ExpectedActorEntityName, got)
} else {
_, ok := result.Metadata["actor_entity_name"]
require.False(t, ok, "actor_entity_name should be absent in auth metadata")
}
})
}
}
// TestMergeEnterpriseTokenMetadata verifies enterprise token claims are copied into auth metadata.
func TestMergeEnterpriseTokenMetadata(t *testing.T) {
t.Parallel()
requestTests := map[string]struct {
Input *logical.Request
ExpectedMetadata string
ExpectedIssuer string
ExpectedTransaction string
}{
"metadata-present": {
Input: &logical.Request{ID: "req-1", EnterpriseTokenMetadata: "token-abc"},
ExpectedMetadata: "token-abc",
},
"metadata-absent": {
Input: &logical.Request{ID: "req-2"},
ExpectedMetadata: "",
},
"issuer-present": {
Input: &logical.Request{
ID: "req-3",
EnterpriseTokenMetadata: "token-xyz",
EnterpriseTokenIssuer: "https://issuer.example.com",
},
ExpectedMetadata: "token-xyz",
ExpectedIssuer: "https://issuer.example.com",
},
"transaction-present": {
Input: &logical.Request{
ID: "req-4",
EnterpriseTokenMetadata: "token-txn",
EnterpriseTokenTransaction: "txn-123",
},
ExpectedMetadata: "token-txn",
ExpectedTransaction: "txn-123",
},
}
for name, tc := range requestTests {
t.Run(name, func(t *testing.T) {
t.Parallel()
a := &auth{}
err := mergeEnterpriseTokenMetadata(a, tc.Input)
require.NoError(t, err)
if tc.ExpectedMetadata == "" && tc.ExpectedIssuer == "" && tc.ExpectedTransaction == "" {
require.Nil(t, a.Metadata)
}
assertMetadataField := func(key, want string) {
t.Helper()
got, ok := a.Metadata[key]
if want == "" {
require.False(t, ok, "%s should be absent in auth metadata", key)
return
}
require.True(t, ok, "%s should be present in auth metadata", key)
require.Equal(t, want, got)
}
assertMetadataField("enterprise_token_metadata", tc.ExpectedMetadata)
assertMetadataField("enterprise_token_issuer", tc.ExpectedIssuer)
assertMetadataField("enterprise_token_transaction", tc.ExpectedTransaction)
})
}
}
// TestEntryFormatter_Process_JSON_EnterpriseToken verifies that enterprise token fields
// (actor_entity_id, actor_entity_name, enterprise_token_metadata, enterprise_token_issuer,
// enterprise_token_transaction,
// enterprise_token_audience, enterprise_token_authorization_details) are correctly
// serialized into auth.metadata in the JSON audit output, and absent when not set.
func TestEntryFormatter_Process_JSON_EnterpriseToken(t *testing.T) {
t.Parallel()
staticSalt := newStaticSalt(t)
authzDetails := []logical.AuthorizationDetail{
{"type": "payment_initiation", "currency": "USD"},
}
cases := map[string]struct {
Auth *logical.Auth
Req *logical.Request
WantActorEntityID string
WantActorEntityName string
WantMetadata string
WantIssuer string
WantTransaction string
WantAudience string
WantAuthorizationDetails string
}{
"enterprise-token-with-actor-and-authorization-details": {
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
DisplayName: "testtoken",
EntityID: "subject-entity-123",
ActorEntityID: "actor-entity-456",
ActorEntityName: "actor-service",
Policies: []string{"default"},
TokenType: logical.TokenTypeDefault,
},
Req: &logical.Request{
Operation: logical.ReadOperation,
Path: "/cubbyhole/test",
EnterpriseTokenMetadata: "test-token-abc",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenTransaction: "txn-actor-1",
EnterpriseTokenAudience: []string{"vault"},
EnterpriseTokenAuthorizationDetails: authzDetails,
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
WantActorEntityID: "actor-entity-456",
WantActorEntityName: "actor-service",
WantMetadata: "test-token-abc",
WantIssuer: "https://issuer.example.com",
WantTransaction: "txn-actor-1",
WantAudience: `["vault"]`,
WantAuthorizationDetails: `[{"currency":"USD","type":"payment_initiation"}]`,
},
"enterprise-token-base-fields-only": {
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
DisplayName: "testtoken",
EntityID: "subject-entity-123",
Policies: []string{"default"},
TokenType: logical.TokenTypeDefault,
},
Req: &logical.Request{
Operation: logical.ReadOperation,
Path: "/cubbyhole/test",
EnterpriseTokenMetadata: "test-token-xyz",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenTransaction: "txn-base-1",
EnterpriseTokenAudience: []string{"vault"},
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
WantMetadata: "test-token-xyz",
WantIssuer: "https://issuer.example.com",
WantTransaction: "txn-base-1",
WantAudience: `["vault"]`,
},
}
for name, tc := range cases {
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
cfg, err := newFormatterConfig(&testHeaderFormatter{}, map[string]string{
"hmac_accessor": "false",
})
require.NoError(t, err)
formatter, err := newEntryFormatter("test", cfg, staticSalt, hclog.NewNullLogger())
require.NoError(t, err)
in := &logical.LogInput{
Auth: tc.Auth,
Request: tc.Req,
}
auditEvent, err := newEvent(RequestType)
require.NoError(t, err)
auditEvent.Data = in
e := &eventlogger.Event{
Type: event.AuditType.AsEventType(),
CreatedAt: time.Now(),
Formatted: make(map[string][]byte),
Payload: auditEvent,
}
e2, err := formatter.Process(nshelper.RootContext(nil), e)
require.NoError(t, err)
jsonBytes, ok := e2.Format(jsonFormat.String())
require.True(t, ok)
require.Positive(t, len(jsonBytes))
var result entry
require.NoError(t, json.Unmarshal(jsonBytes, &result))
require.NotNil(t, result.Auth)
require.Equal(t, tc.WantActorEntityID, result.Auth.Metadata["actor_entity_id"])
require.Equal(t, tc.WantActorEntityName, result.Auth.Metadata["actor_entity_name"])
require.NotNil(t, result.Request)
require.Equal(t, tc.WantMetadata, result.Auth.Metadata["enterprise_token_metadata"])
require.Equal(t, tc.WantIssuer, result.Auth.Metadata["enterprise_token_issuer"])
require.Equal(t, tc.WantTransaction, result.Auth.Metadata["enterprise_token_transaction"])
require.Equal(t, tc.WantAudience, result.Auth.Metadata["enterprise_token_audience"])
require.Equal(t, tc.WantAuthorizationDetails, result.Auth.Metadata["enterprise_token_authorization_details"])
})
}
}
// TestEntryFormatter_Process_Response_EnterpriseToken verifies that enterprise token
// fields are injected into both the top-level auth.metadata AND the response auth.metadata.
func TestEntryFormatter_Process_Response_EnterpriseToken(t *testing.T) {
t.Parallel()
staticSalt := newStaticSalt(t)
cfg, err := newFormatterConfig(&testHeaderFormatter{}, map[string]string{
"hmac_accessor": "false",
})
require.NoError(t, err)
formatter, err := newEntryFormatter("test", cfg, staticSalt, hclog.NewNullLogger())
require.NoError(t, err)
in := &logical.LogInput{
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
DisplayName: "testtoken",
EntityID: "subject-entity-123",
ActorEntityID: "actor-entity-456",
ActorEntityName: "actor-service",
Policies: []string{"default"},
TokenType: logical.TokenTypeDefault,
},
Request: &logical.Request{
Operation: logical.ReadOperation,
Path: "/secret/data/test",
EnterpriseTokenMetadata: "resp-token-abc",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenTransaction: "txn-response-1",
EnterpriseTokenAudience: []string{"vault", "api"},
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
Response: &logical.Response{
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
EntityID: "subject-entity-123",
Policies: []string{"default"},
TokenType: logical.TokenTypeDefault,
},
Data: map[string]interface{}{
"value": "secret",
},
},
}
auditEvent, err := newEvent(ResponseType)
require.NoError(t, err)
auditEvent.Data = in
e := &eventlogger.Event{
Type: event.AuditType.AsEventType(),
CreatedAt: time.Now(),
Formatted: make(map[string][]byte),
Payload: auditEvent,
}
e2, err := formatter.Process(nshelper.RootContext(nil), e)
require.NoError(t, err)
jsonBytes, ok := e2.Format(jsonFormat.String())
require.True(t, ok)
var result entry
require.NoError(t, json.Unmarshal(jsonBytes, &result))
// Top-level auth must have enterprise token fields in metadata
require.NotNil(t, result.Auth)
require.Equal(t, "actor-entity-456", result.Auth.Metadata["actor_entity_id"])
require.Equal(t, "actor-service", result.Auth.Metadata["actor_entity_name"])
require.Equal(t, "resp-token-abc", result.Auth.Metadata["enterprise_token_metadata"])
require.Equal(t, "https://issuer.example.com", result.Auth.Metadata["enterprise_token_issuer"])
require.Equal(t, "txn-response-1", result.Auth.Metadata["enterprise_token_transaction"])
require.Equal(t, `["vault","api"]`, result.Auth.Metadata["enterprise_token_audience"])
// Response auth must also have enterprise token fields in metadata
require.NotNil(t, result.Response)
require.NotNil(t, result.Response.Auth)
require.Equal(t, "resp-token-abc", result.Response.Auth.Metadata["enterprise_token_metadata"])
require.Equal(t, "https://issuer.example.com", result.Response.Auth.Metadata["enterprise_token_issuer"])
require.Equal(t, "txn-response-1", result.Response.Auth.Metadata["enterprise_token_transaction"])
require.Equal(t, `["vault","api"]`, result.Response.Auth.Metadata["enterprise_token_audience"])
}
// TestEntryFormatter_EnterpriseTokenFieldsNotOnRequestOrAuthTopLevel verifies that
// enterprise token fields do NOT appear as top-level JSON keys on the request or auth
// structs — they must only be in auth.metadata.
func TestEntryFormatter_EnterpriseTokenFieldsNotOnRequestOrAuthTopLevel(t *testing.T) {
t.Parallel()
staticSalt := newStaticSalt(t)
cfg, err := newFormatterConfig(&testHeaderFormatter{}, map[string]string{
"hmac_accessor": "false",
})
require.NoError(t, err)
formatter, err := newEntryFormatter("test", cfg, staticSalt, hclog.NewNullLogger())
require.NoError(t, err)
in := &logical.LogInput{
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
DisplayName: "testtoken",
EntityID: "foobarentity",
ActorEntityID: "actor-entity-789",
ActorEntityName: "actor-service",
Policies: []string{"root"},
TokenType: logical.TokenTypeService,
},
Request: &logical.Request{
Operation: logical.ReadOperation,
Path: "/secret/data/test",
EnterpriseTokenMetadata: "test-token-123",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenTransaction: "txn-top-level-1",
EnterpriseTokenAudience: []string{"vault"},
EnterpriseTokenAuthorizationDetails: []logical.AuthorizationDetail{{"type": "access"}},
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
}
auditEvent, err := newEvent(RequestType)
require.NoError(t, err)
auditEvent.Data = in
e := &eventlogger.Event{
Type: event.AuditType.AsEventType(),
CreatedAt: time.Now(),
Formatted: make(map[string][]byte),
Payload: auditEvent,
}
e2, err := formatter.Process(nshelper.RootContext(nil), e)
require.NoError(t, err)
jsonBytes, ok := e2.Format(jsonFormat.String())
require.True(t, ok)
var raw map[string]json.RawMessage
require.NoError(t, json.Unmarshal(jsonBytes, &raw))
// Auth top-level must NOT have actor_entity_id or actor_entity_name
var authMap map[string]json.RawMessage
require.NoError(t, json.Unmarshal(raw["auth"], &authMap))
_, hasActorEntityID := authMap["actor_entity_id"]
_, hasActorEntityName := authMap["actor_entity_name"]
require.False(t, hasActorEntityID, "actor_entity_id must not be a top-level auth field")
require.False(t, hasActorEntityName, "actor_entity_name must not be a top-level auth field")
// Request top-level must NOT have any enterprise_token_* fields
var reqMap map[string]json.RawMessage
require.NoError(t, json.Unmarshal(raw["request"], &reqMap))
for key := range reqMap {
require.False(t, strings.HasPrefix(key, "enterprise_token_"),
"request must not have top-level enterprise_token_ field: %s", key)
}
// But auth.metadata MUST have them
var metadataMap map[string]string
require.NoError(t, json.Unmarshal(authMap["metadata"], &metadataMap))
entityID, ok := metadataMap["actor_entity_id"]
require.True(t, ok)
require.Equal(t, "actor-entity-789", entityID)
entityName, ok := metadataMap["actor_entity_name"]
require.True(t, ok)
require.Equal(t, "actor-service", entityName)
tokenMetadata, ok := metadataMap["enterprise_token_metadata"]
require.True(t, ok)
require.Equal(t, "test-token-123", tokenMetadata)
tokenIssuer, ok := metadataMap["enterprise_token_issuer"]
require.True(t, ok)
require.Equal(t, "https://issuer.example.com", tokenIssuer)
tokenTransaction, ok := metadataMap["enterprise_token_transaction"]
require.True(t, ok)
require.Equal(t, "txn-top-level-1", tokenTransaction)
tokenAudience, ok := metadataMap["enterprise_token_audience"]
require.True(t, ok)
require.Equal(t, `["vault"]`, tokenAudience)
tokenAuthzDetails, ok := metadataMap["enterprise_token_authorization_details"]
require.True(t, ok)
require.Contains(t, tokenAuthzDetails, `"type":"access"`)
}
// TestEntryFormatter_Process_Request exercises entryFormatter process an event
// with varying inputs.
func TestEntryFormatter_Process_Request(t *testing.T) {
@ -788,6 +1279,40 @@ func TestEntryFormatter_Process_JSON(t *testing.T) {
"@cee: ",
expectedResultStr,
},
"auth, request with enterprise token": {
&logical.Auth{
ClientToken: "foo",
Accessor: "bar",
DisplayName: "testtoken",
EntityID: "foobarentity",
ActorEntityID: "actor-entity-789",
ActorEntityName: "actor-service",
NoDefaultPolicy: true,
Policies: []string{"root"},
TokenType: logical.TokenTypeService,
LeaseOptions: logical.LeaseOptions{
TTL: time.Hour * 4,
IssueTime: issueTime,
},
},
&logical.Request{
Operation: logical.UpdateOperation,
Path: "/foo",
EnterpriseTokenMetadata: "test-token-123",
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
WrapInfo: &logical.RequestWrapInfo{
TTL: 60 * time.Second,
},
Headers: map[string][]string{
"foo": {"bar"},
},
},
errors.New("this is an error"),
"",
fmt.Sprintf(testFormatJSONEnterpriseTokenStrFmt, ss.salt.GetIdentifiedHMAC("foo")),
},
}
for name, tc := range cases {
@ -831,7 +1356,7 @@ func TestEntryFormatter_Process_JSON(t *testing.T) {
expectedJSON := new(entry)
if err := jsonutil.DecodeJSON([]byte(expectedResultStr), &expectedJSON); err != nil {
if err := jsonutil.DecodeJSON([]byte(tc.ExpectedStr), &expectedJSON); err != nil {
t.Fatalf("bad json: %s", err)
}
expectedJSON.Request.Namespace = &namespace{ID: "root"}
@ -1190,7 +1715,73 @@ func TestEntryFormatter_Process_NoMutation(t *testing.T) {
require.NotEqual(t, e2, e)
}
// TestEntryFormatter_Process_Panic tries to send data into the entryFormatter
// TestEntryFormatter_Process_NoMutation_WithEnterpriseToken verifies that
// formatting an event carrying enterprise token fields does not mutate the
// original logical.Request. The EnterpriseToken* fields must be identical on
// the input after Process returns.
func TestEntryFormatter_Process_NoMutation_WithEnterpriseToken(t *testing.T) {
t.Parallel()
cfg, err := newFormatterConfig(&testHeaderFormatter{}, nil)
require.NoError(t, err)
staticSalt := newStaticSalt(t)
formatter, err := newEntryFormatter("no-mutation-ent-token", cfg, staticSalt, hclog.NewNullLogger())
require.NoError(t, err)
require.NotNil(t, formatter)
authzDetails := []logical.AuthorizationDetail{
{
"type": "vault:path_access",
"path_constraint": "secret/data/users/alice",
"action": "read",
},
}
in := &logical.LogInput{
Auth: &logical.Auth{
ClientToken: "foo",
Accessor: "bar",
EntityID: "subject-entity-123",
ActorEntityID: "actor-entity-456",
ActorEntityName: "actor-service",
DisplayName: "testtoken",
Policies: []string{"default"},
TokenType: logical.TokenTypeService,
},
Request: &logical.Request{
Operation: logical.ReadOperation,
Path: "/cubbyhole/test",
EnterpriseTokenMetadata: "test-token-abc",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenAudience: []string{"vault", "api"},
EnterpriseTokenAuthorizationDetails: authzDetails,
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
}
// Snapshot the enterprise token field values before processing.
wantMetadata := in.Request.EnterpriseTokenMetadata
wantIssuer := in.Request.EnterpriseTokenIssuer
wantAudience := append([]string(nil), in.Request.EnterpriseTokenAudience...)
e := fakeEvent(t, RequestType, in)
e2, err := formatter.Process(nshelper.RootContext(nil), e)
require.NoError(t, err)
require.NotNil(t, e2)
// The event pointer must differ — no in-place mutation.
require.NotEqual(t, e2, e)
// The original request's enterprise token fields must be unchanged.
require.Equal(t, wantMetadata, in.Request.EnterpriseTokenMetadata)
require.Equal(t, wantIssuer, in.Request.EnterpriseTokenIssuer)
require.Equal(t, wantAudience, in.Request.EnterpriseTokenAudience)
require.Equal(t, authzDetails, in.Request.EnterpriseTokenAuthorizationDetails)
}
// which will currently cause a panic when a response is formatted due to the
// underlying hashing that is done with reflectwalk.
func TestEntryFormatter_Process_Panic(t *testing.T) {

View file

@ -432,3 +432,71 @@ func TestHashWalker_TimeStructs(t *testing.T) {
}
}
}
// TestCopy_request_EnterpriseTokenFields verifies that copystructure.Copy
// correctly deep-copies a logical.Request that carries enterprise token fields,
// including EnterpriseTokenAuthorizationDetails which is []map[string]any and
// would silently lose data under a shallow copy.
func TestCopy_request_EnterpriseTokenFields(t *testing.T) {
expected := logical.Request{
Data: map[string]interface{}{
"foo": "bar",
},
EnterpriseTokenMetadata: "test-token-abc",
EnterpriseTokenIssuer: "https://issuer.example.com",
EnterpriseTokenTransaction: "txn-copy-1",
EnterpriseTokenAudience: []string{"vault", "api"},
EnterpriseTokenAuthorizationDetails: []logical.AuthorizationDetail{
{
"type": "vault:path_access",
"path_constraint": "secret/data/users/alice",
"action": "read",
},
{
"type": "vault:path_access",
"path_constraint": "secret/data/config/general",
"action": "update",
},
},
}
arg := expected
dup, err := copystructure.Copy(&arg)
require.NoError(t, err)
arg2 := dup.(*logical.Request)
require.EqualValues(t, expected, *arg2)
}
// TestHashRequest_EnterpriseTokenFieldsInMetadata verifies that enterprise token
// fields stored in auth.Metadata are not HMAC'd by hashAuth. These values are
// not secrets and must appear as cleartext in the audit log.
func TestHashRequest_EnterpriseTokenFieldsInMetadata(t *testing.T) {
// Enterprise token fields are now stored in auth.Metadata by createEntry().
// Verify that hashAuth does not HMAC metadata values.
auditAuth := &auth{
ClientToken: "secret-token",
Metadata: map[string]string{
"enterprise_token_metadata": "test-token-xyz",
"enterprise_token_issuer": "https://issuer.example.com",
"enterprise_token_transaction": "txn-hash-1",
"actor_entity_id": "actor-123",
"actor_entity_name": "actor-service",
},
}
salter := &testSalter{}
err := hashAuth(context.Background(), salter, auditAuth, false)
require.NoError(t, err)
// ClientToken must be HMAC'd — it is a secret.
require.NotEqual(t, "secret-token", auditAuth.ClientToken)
require.Contains(t, auditAuth.ClientToken, "hmac-sha256:")
// Metadata values must pass through unchanged — they are not secrets.
require.Equal(t, "test-token-xyz", auditAuth.Metadata["enterprise_token_metadata"])
require.Equal(t, "https://issuer.example.com", auditAuth.Metadata["enterprise_token_issuer"])
require.Equal(t, "txn-hash-1", auditAuth.Metadata["enterprise_token_transaction"])
require.Equal(t, "actor-123", auditAuth.Metadata["actor_entity_id"])
require.Equal(t, "actor-service", auditAuth.Metadata["actor_entity_name"])
}

View file

@ -20,7 +20,6 @@ func TestBackend_E2E_Initialize(t *testing.T) {
// Set up the cluster. This will trigger an Initialize(); we sleep briefly
// awaiting its completion.
cluster := setupAwsTestCluster(t, ctx)
defer cluster.Cleanup()
time.Sleep(time.Second)
core := cluster.Cores[0]
@ -112,12 +111,10 @@ func setupAwsTestCluster(t *testing.T, _ context.Context) *vault.TestCluster {
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
if len(cluster.Cores) != 1 {
t.Fatalf("expected exactly one core")
}
core := cluster.Cores[0]
vault.TestWaitActive(t, core.Core)
// load the auth plugin
if err := core.Client.Sys().EnableAuthWithOptions("aws", &api.EnableAuthOptions{

View file

@ -368,14 +368,26 @@ func (b *backend) pathConfigClientCreateUpdate(ctx context.Context, req *logical
configEntry.RoleARN = data.Get("role_arn").(string)
}
// Checking if identity_token_ttl is actually changed, no need to flush the cache if it is not
previousIdentityParams := configEntry.PluginIdentityTokenParams
if err := configEntry.ParsePluginIdentityTokenFields(data); err != nil {
return logical.ErrorResponse(err.Error()), nil
}
if !previousIdentityParams.Equals(configEntry.PluginIdentityTokenParams) {
changedCreds = true
}
// Checking if any for the rotation parameters has been modified, if yes, we set "changedOtherConfig" to true
previousRotationParams := configEntry.AutomatedRotationParams
if err := configEntry.ParseAutomatedRotationFields(data); err != nil {
return logical.ErrorResponse(err.Error()), nil
}
if !previousRotationParams.Equals(configEntry.AutomatedRotationParams) {
changedOtherConfig = true
}
// handle mutual exclusivity
if configEntry.IdentityTokenAudience != "" && configEntry.AccessKey != "" {
return logical.ErrorResponse("only one of 'access_key' or 'identity_token_audience' can be set"), nil

View file

@ -187,3 +187,39 @@ func (d testSystemView) RegisterRotationJob(_ context.Context, _ *rotation.Rotat
func (d testSystemView) DeregisterRotationJob(_ context.Context, _ *rotation.RotationJobDeregisterRequest) error {
return nil
}
// TestBackend_PathConfigClient_RotationParameters tests that configuration
// of root creds rotation returns an immediate error.
func TestBackend_PathConfigClient_RotationParameters(t *testing.T) {
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
config.System = &testSystemView{}
b, err := Backend(config)
if err != nil {
t.Fatal(err)
}
err = b.Setup(context.Background(), config)
if err != nil {
t.Fatal(err)
}
configData := map[string]interface{}{
"disable_automated_rotation": "false",
"rotation_schedule": "0 2 1-7 * TUE",
"rotation_window": "1h",
}
configReq := &logical.Request{
Operation: logical.UpdateOperation,
Storage: config.StorageView,
Path: "config/client",
Data: configData,
}
resp, err := b.HandleRequest(context.Background(), configReq)
assert.NoError(t, err)
assert.NotNil(t, resp)
assert.ErrorContains(t, resp.Error(), automatedrotationutil.ErrRotationManagerUnsupported.Error())
}

View file

@ -563,7 +563,7 @@ func (b *backend) upgradeRole(ctx context.Context, s logical.Storage, roleEntry
roleEntry.Version = currentRoleStorageVersion
default:
return false, fmt.Errorf("unrecognized role version: %q", roleEntry.Version)
return false, fmt.Errorf("unrecognized role version: %d", roleEntry.Version)
}
// Add tokenutil upgrades. These don't need to be persisted, they're fine

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,16 @@ package cert
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io/ioutil"
"math/big"
"net"
"net/http"
"net/http/httptest"
"net/url"
@ -55,14 +59,87 @@ func TestCRLFetch(t *testing.T) {
if err != nil {
t.Fatalf("error: %s", err)
}
connState, err := testConnState("test-fixtures/keys/cert.pem",
"test-fixtures/keys/key.pem", "test-fixtures/root/rootcacert.pem")
// Generate CA certificate
caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
caPEM, err := ioutil.ReadFile("test-fixtures/root/rootcacert.pem")
caTemplate := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: "Test CA",
},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
BasicConstraintsValid: true,
IsCA: true,
}
caCertBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &caKey.PublicKey, caKey)
require.NoError(t, err)
caKeyPEM, err := ioutil.ReadFile("test-fixtures/keys/key.pem")
caCert, err := x509.ParseCertificate(caCertBytes)
require.NoError(t, err)
caPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: caCertBytes,
})
caKeyBytes, err := x509.MarshalECPrivateKey(caKey)
require.NoError(t, err)
caKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "EC PRIVATE KEY",
Bytes: caKeyBytes,
})
// Generate client certificate
clientKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
clientTemplate := &x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{
CommonName: "test.example.com",
},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{"localhost", "test.example.com"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
}
clientCertBytes, err := x509.CreateCertificate(rand.Reader, clientTemplate, caCert, &clientKey.PublicKey, caKey)
require.NoError(t, err)
certPEM := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: clientCertBytes,
})
clientKeyBytes, err := x509.MarshalECPrivateKey(clientKey)
require.NoError(t, err)
clientKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "EC PRIVATE KEY",
Bytes: clientKeyBytes,
})
// Create tls.Certificate from PEM data
tlsCert, err := tls.X509KeyPair(certPEM, clientKeyPEM)
require.NoError(t, err)
// Create CA cert pool
rootCAs := x509.NewCertPool()
rootCAs.AppendCertsFromPEM(caPEM)
// Create connection state with generated certificates
connState, err := testConnStateWithCert(tlsCert, rootCAs)
require.NoError(t, err)
certPEM, err := ioutil.ReadFile("test-fixtures/keys/cert.pem")
caBundle, err := certutil.ParsePEMBundle(string(caPEM))
require.NoError(t, err)
@ -80,7 +157,7 @@ func TestCRLFetch(t *testing.T) {
Number: big.NewInt(1),
ThisUpdate: time.Now(),
NextUpdate: time.Now().Add(50 * time.Millisecond),
SignatureAlgorithm: x509.SHA1WithRSA,
SignatureAlgorithm: x509.ECDSAWithSHA256,
}
var crlBytesLock sync.Mutex

View file

@ -1,20 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDPjCCAiagAwIBAgIUXiEDuecwua9+j1XHLnconxQ/JBcwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLbXl2YXVsdC5jb20wIBcNMTYwNTAyMTYwMzU4WhgPMjA2
NjA0MjAxNjA0MjhaMBYxFDASBgNVBAMTC215dmF1bHQuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWPjnTqnkc6acah+wWLmdTK0oCrf2687XVhx
VP3IN897TYzkaBQ2Dn1UM2VEL71sE3OZSVm0UWs5n7UqRuDp6mvkvrT2q5zgh/bV
zg9ZL1AI5H7dY2Rsor95I849ymFpXZooMgNtIQLxIeleBwzTnVSkFl8RqKM7NkjZ
wvBafQEjSsYk9050Bu0GMLgFJYRo1LozJLbwIs5ykG5F5PWTMfRvLCgLBzixPb75
unIJ29nL0yB7zzUdkM8CG1EX8NkjGLEnpRnPa7+RMf8bd10v84cr0JFCUQmoabks
sqVyA825/1we2r5Y8blyXZVIr2lcPyGocLDxz1qT1MqxrNQIywIDAQABo4GBMH8w
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBTo2I+W
3Wb2MBe3OWuj5qCbafavMB8GA1UdIwQYMBaAFBTo2I+W3Wb2MBe3OWuj5qCbafav
MBwGA1UdEQQVMBOCC215dmF1bHQuY29thwR/AAABMA0GCSqGSIb3DQEBCwUAA4IB
AQAyjJzDMzf28yMgiu//2R6LD3+zuLHlfX8+p5JB7WDBT7CgSm89gzMRtD2DvqZQ
6iLbZv/x7Td8bdLsOKf3LDCkZyOygJ0Sr9+6YZdc9heWO8tsO/SbcLhj9/vK8YyV
5fJo+vECW8I5zQLeTKfPqJtTU0zFspv0WYCB96Hsbhd1hTfHmVgjBoxi0YuduAa8
3EHuYPfTYkO3M4QJCoQ+3S6LXSTDqppd1KGAy7QhRU6shd29EpSVxhgqZ+CIOpZu
3RgPOgPqfqcOD/v/SRPqhRf+P5O5Dc/N4ZXTZtfJbaY0qE+smpeQUskVQ2TrSqha
UYpNk7+toZW3Gioo0lBD3gH2
-----END CERTIFICATE-----

View file

@ -1,12 +0,0 @@
-----BEGIN X509 CRL-----
MIIBrjCBlzANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtteXZhdWx0LmNvbRcN
MTYwNTAyMTYxNDMzWhcNMTYwNTA1MTYxNDMzWjArMCkCFCXxxcbS0ATpI2PYrx8d
ACLEQ3B9FxExNjA1MDIxMjE0MzMtMDQwMKAjMCEwHwYDVR0jBBgwFoAUwsRNYCw4
U2won66rMKEJm8inFfgwDQYJKoZIhvcNAQELBQADggEBAD/VvoRK4eaEDzG7Z95b
fHL5ubJGkyvkp8ruNu+rfQp8NLgFVvY6a93Hz7WLOhACkKIWJ63+/4vCfDi5uU0B
HW2FICHdlSQ+6DdGJ6MrgujALlyT+69iF+fPiJ/M1j/N7Am8XPYYcfNdSK6CHtfg
gHNB7E+ubBA7lIw7ucIkoiJjXrSWSXTs9/GzLUImiXJAKQ+JzPYryIsGKXKAwgHh
HB56BnJ2vOs7+6UxQ6fjKTMxYdNgoZ34MhkkxNNhylrEndO6XUvUvC1f/1p1wlzy
xTq2MrMfJHJyu08rkrD+kwMPH2uoVwKyDhXdRBP0QrvQwOsvNEhW8LTKwLWkK17b
fEI=
-----END X509 CRL-----

View file

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAwWPjnTqnkc6acah+wWLmdTK0oCrf2687XVhxVP3IN897TYzk
aBQ2Dn1UM2VEL71sE3OZSVm0UWs5n7UqRuDp6mvkvrT2q5zgh/bVzg9ZL1AI5H7d
Y2Rsor95I849ymFpXZooMgNtIQLxIeleBwzTnVSkFl8RqKM7NkjZwvBafQEjSsYk
9050Bu0GMLgFJYRo1LozJLbwIs5ykG5F5PWTMfRvLCgLBzixPb75unIJ29nL0yB7
zzUdkM8CG1EX8NkjGLEnpRnPa7+RMf8bd10v84cr0JFCUQmoabkssqVyA825/1we
2r5Y8blyXZVIr2lcPyGocLDxz1qT1MqxrNQIywIDAQABAoIBAD1pBd9ov8t6Surq
sY2hZUM0Hc16r+ln5LcInbx6djjaxvHiWql+OYgyXimP764lPYuTuspjFPKB1SOU
+N7XDxCkwFeayXXHdDlYtZ4gm5Z9mMVOT+j++8xWdxZaqJ56fmX9zOPM2LuR3paB
L52Xgh9EwHJmMApYAzaCvbu8bU+iHeNTW80xabxQrp9VCu/A1BXUX06jK4T+wmjZ
kDA82uQp3dCOF1tv/10HgwqkJj6/1jjM0XUzUZR6iV85S6jrA7wD7gDDeqNO8YHN
08YMRgTKk4pbA7AqoC5xbL3gbSjsjyw48KRq0FkdkjsgV0PJZRMUU9fv9puDa23K
WRPa8LECgYEAyeth5bVH8FXnVXIAAFU6W0WdgCK3VakhjItLw0eoxshuTwbVq64w
CNOB8y1pfP83WiJjX3qRG43NDW07X69J57YKtCCb6KICVUPmecgYZPkmegD1HBQZ
5+Aak+5pIUQuycQ0t65yHGu4Jsju05gEFgdzydFjNANgiPxRzZxzAkkCgYEA9S+y
ZR063oCQDg/GhMLCx19nCJyU44Figh1YCD6kTrsSTECuRpQ5B1F9a+LeZT2wnYxv
+qMvvV+lfVY73f5WZ567u2jSDIsCH34p4g7sE25lKwo+Lhik6EtOehJFs2ZUemaT
Ym7EjqWlC1whrG7P4MnTGzPOVNAGAxsGPtT58nMCgYAs/R8A2VU//UPfy9ioOlUY
RPiEtjd3BIoPEHI+/lZihAHf5bvx1oupS8bmcbXRPeQNVyAhA+QU6ZFIbpAOD7Y9
xFe6LpHOUVqHuOs/MxAMX17tTA1QxkHHYi1JzJLr8I8kMW01h86w+mc7bQWZa4Nt
jReFXfvmeOInY2CumS8e0QKBgC23ow/vj1aFqla04lNG7YK3a0LTz39MVM3mItAG
viRgBV1qghRu9uNCcpx3RPijtBbsZMTbQL+S4gyo06jlD79qfZ7IQMJN+SteHvkj
xykoYHzSAB4gQj9+KzffyFdXMVFRZxHnjYb7o/amSzEXyHMlrtNXqZVu5HAXzeZR
V/m5AoGAAStS43Q7qSJSMfMBITKMdKlqCObnifD77WeR2WHGrpkq26300ggsDpMS
UTmnAAo77lSMmDsdoNn2XZmdeTu1CPoQnoZSE5CqPd5GeHA/hhegVCdeYxSXZJoH
Lhiac+AhCEog/MS1GmVsjynD7eDGVFcsJ6SWuam7doKfrpPqPnE=
-----END RSA PRIVATE KEY-----

View file

@ -1,67 +0,0 @@
vault mount pki
vault mount-tune -max-lease-ttl=438000h pki
vault write pki/root/generate/exported common_name=myvault.com ttl=438000h ip_sans=127.0.0.1
vi cacert.pem
vi cakey.pem
vaultcert.hcl
backend "inmem" {
}
disable_mlock = true
default_lease_ttl = "700h"
max_lease_ttl = "768h"
listener "tcp" {
address = "127.0.0.1:8200"
tls_cert_file = "./cacert.pem"
tls_key_file = "./cakey.pem"
}
========================================
vault mount pki
vault mount-tune -max-lease-ttl=438000h pki
vault write pki/root/generate/exported common_name=myvault.com ttl=438000h max_ttl=438000h ip_sans=127.0.0.1
vi testcacert1.pem
vi testcakey1.pem
vi testcaserial1
vault write pki/config/urls issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"
vault write pki/roles/myvault-dot-com allowed_domains=myvault.com allow_subdomains=true ttl=437999h max_ttl=438000h allow_ip_sans=true
vault write pki/issue/myvault-dot-com common_name=cert.myvault.com format=pem ip_sans=127.0.0.1
vi testissuedserial1
vault write pki/issue/myvault-dot-com common_name=cert.myvault.com format=pem ip_sans=127.0.0.1
vi testissuedcert2.pem
vi testissuedkey2.pem
vi testissuedserial2
vault write pki/issue/myvault-dot-com common_name=cert.myvault.com format=pem ip_sans=127.0.0.1
vi testissuedserial3
vault write pki/issue/myvault-dot-com common_name=cert.myvault.com format=pem ip_sans=127.0.0.1
vi testissuedcert4.pem
vi testissuedkey4.pem
vi testissuedserial4
vault write pki/issue/myvault-dot-com common_name=cert.myvault.com format=pem ip_sans=127.0.0.1
vi testissuedserial5
vault write pki/revoke serial_number=$(cat testissuedserial2)
vault write pki/revoke serial_number=$(cat testissuedserial4)
curl -XGET "http://127.0.0.1:8200/v1/pki/crl/pem" -H "x-vault-token:123" > issuedcertcrl
openssl crl -in issuedcertcrl -noout -text
========================================
export VAULT_ADDR='http://127.0.0.1:8200'
vault mount pki
vault mount-tune -max-lease-ttl=438000h pki
vault write pki/root/generate/exported common_name=myvault.com ttl=438000h ip_sans=127.0.0.1
vi testcacert2.pem
vi testcakey2.pem
vi testcaserial2
vi testcacert2leaseid
vault write pki/config/urls issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"
vault revoke $(cat testcacert2leaseid)
curl -XGET "http://127.0.0.1:8200/v1/pki/crl/pem" -H "x-vault-token:123" > cacert2crl
openssl crl -in cacert2crl -noout -text

View file

@ -1,12 +0,0 @@
-----BEGIN X509 CRL-----
MIIB2TCBwjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtteXZhdWx0LmNvbRcN
MTYwNTAyMTYxMTA4WhcNMTYwNTA1MTYxMTA4WjBWMCkCFAS6oenLRllQ1MRYcSV+
5ukv2563FxExNjA1MDIxMjExMDgtMDQwMDApAhQaQdPJfbIwE3q4nyYp60lVnZaE
5hcRMTYwNTAyMTIxMTA1LTA0MDCgIzAhMB8GA1UdIwQYMBaAFOuKvPiUG06iHkRX
AOeMiUdBfHFyMA0GCSqGSIb3DQEBCwUAA4IBAQBD2jkeOAmkDdYkAXbmjLGdHaQI
WMS/M+wtFnHVIDVQEmUmj/KPsrkshTZv2UgCHIxBha6y+kXUMQFMg6FwriDTB170
WyJVDVhGg2WjiQjnzrzEI+iOmcpx60sPPXE63J/Zxo4QS5M62RTXRq3909HQTFI5
f3xf0pog8mOrv5uQxO1SACP6YFtdDE2dGOVwoIPuNMTY5vijnj8I9dAw8VrbdoBX
m/Ky56kT+BpmVWHKwQd1nEcP/RHSKbZwwJzJG0BoGM8cvzjITtBmpEF+OZcea81x
p9XJkpfFeiVIgzxks3zTeuQjLF8u+MDcdGt0ztHEbkswjxuk1cCovZe2GFr4
-----END X509 CRL-----

View file

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCAf6gAwIBAgIJAJIiPq+77hewMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
BAMTC2V4YW1wbGUuY29tMCAXDTI1MDYxODE5MzEzM1oYDzIwNTAwNjE5MTkzMTMz
WjAWMRQwEgYDVQQDDAtub3RmYWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALGcdEr6/NmCaRaSMuHyTVuXygOgfJocUk0QFZ8oAH7XrU/Kbh35
WNLLO2Ol9jl47FND0Z/tT7MLYr4Sovni7YFpFBfXBWBRp0oDJXemVkYTYXmYQOmX
0JnjPwRdqWuRytkgxd+pY4Iy/U/p1q67tlL9AQqB8ywJomGDIiFqZYnTJjDuTU0R
t5PtwDdE5H2pAeiVc4yxoU3F3TnFRDF5HkFaiTALhqLlOXaJ8qrZ2h7iCRrlHcue
GA51/OrcYTkIQL+q+3R182cUuKZi78PFCNa7En/xi3FFRgfufgABheYrhwtzdg05
eMc9xXDeAm+MPaW2kO/pgs8/mp6oiX8q9p8CAwEAAaNlMGMwIQYDVR0RBBowGIIQ
Y2VydC5leGFtcGxlLmNvbYcEfwAAATAdBgNVHQ4EFgQUmuMiWgeoyPlkEyXcJ7Og
qJotlJkwHwYDVR0jBBgwFoAUncSzT/6HMexyuiU9/7EgHu+ok5swDQYJKoZIhvcN
AQELBQADggEBANYE2poNMZakvN2a8hGbVHNXCR4+j5dE/nIw0ZW2PPv4CuNJ3whN
G15MT790k9DiNNecJBP32jwAOedIWKr3aqasur4eXA8xhN1nbtJODWxXYaV3USs7
C1Mu9DV3aRiyFhEv6Va6RL4gCnOqOZdXG1+dAkughBKrRNJAMo5Wop/VC8rkSssO
NpQBt7ROIJjyTXrHQq23HR/uVv511AE5hDMDzxaVbsslBuzhD4nHOJ/Y/LWcXHJ1
8W6S1vgSES2lo8U5tthSE4WyYW6kH6r2hBrK4ESdpdAUfO/lVNCe5KeYYWRwzMOw
oj9OOxBsjSX5C368IWM4sAn08mYJUUmq3i4=
-----END CERTIFICATE-----

View file

@ -1,18 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIC2zCCAcOgAwIBAgIJAJIiPq+77hewMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
BAMTC2V4YW1wbGUuY29tMCAXDTI1MDEwNjE0MzgzMloYDzIwNTAwMTA3MTQzODMy
WjAbMRkwFwYDVQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAsZx0Svr82YJpFpIy4fJNW5fKA6B8mhxSTRAVnygAftet
T8puHflY0ss7Y6X2OXjsU0PRn+1PswtivhKi+eLtgWkUF9cFYFGnSgMld6ZWRhNh
eZhA6ZfQmeM/BF2pa5HK2SDF36ljgjL9T+nWrru2Uv0BCoHzLAmiYYMiIWplidMm
MO5NTRG3k+3AN0TkfakB6JVzjLGhTcXdOcVEMXkeQVqJMAuGouU5donyqtnaHuIJ
GuUdy54YDnX86txhOQhAv6r7dHXzZxS4pmLvw8UI1rsSf/GLcUVGB+5+AAGF5iuH
C3N2DTl4xz3FcN4Cb4w9pbaQ7+mCzz+anqiJfyr2nwIDAQABoyUwIzAhBgNVHREE
GjAYghBjZXJ0LmV4YW1wbGUuY29thwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQB/
0M2jZ8cZJW23s1xpMDS5u2ScrW4QdpVsPbuBu5dxi3SNx7MK0CbvcNVUEZE0WV6b
rCYvYS0+SBi0skudHRV7IeRADPcvzbXY/AdFktWt0adtQ/5B/DKeZIRrnhGtlzhD
m8b3TTnKLoGdV7iS5HO8emvlzaihY/5PjObkztLRLLDRmBAOwYv4z/xBhEqZJRV1
Ztywy/Qy5srNJug+sHmj8JlBldob/Ohk7Eon04XvXMuCIBptPG/QytnmgGbDGghD
WO/HpCWBh6GHrwzQtof8y7Upxi16i5DSiFbRwNXgRyST4W/ChpZoggvOJ/RI4o2g
5serAZLPfBGztdRbTef2
-----END CERTIFICATE-----

View file

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsZx0Svr82YJpFpIy4fJNW5fKA6B8mhxSTRAVnygAftetT8pu
HflY0ss7Y6X2OXjsU0PRn+1PswtivhKi+eLtgWkUF9cFYFGnSgMld6ZWRhNheZhA
6ZfQmeM/BF2pa5HK2SDF36ljgjL9T+nWrru2Uv0BCoHzLAmiYYMiIWplidMmMO5N
TRG3k+3AN0TkfakB6JVzjLGhTcXdOcVEMXkeQVqJMAuGouU5donyqtnaHuIJGuUd
y54YDnX86txhOQhAv6r7dHXzZxS4pmLvw8UI1rsSf/GLcUVGB+5+AAGF5iuHC3N2
DTl4xz3FcN4Cb4w9pbaQ7+mCzz+anqiJfyr2nwIDAQABAoIBAHR7fFV0eAGaopsX
9OD0TUGlsephBXb43g0GYHfJ/1Ew18w9oaxszJEqkl+PB4W3xZ3yG3e8ZomxDOhF
RreF2WgG5xOfhDogMwu6NodbArfgnAvoC6JnW3qha8HMP4F500RFVyCRcd6A3Frd
rFtaZn/UyCsBAN8/zkwPeYHayo7xX6d9kzgRl9HluEX5PXI5+3uiBDUiM085gkLI
5Cmadh9fMdjfhDXI4x2JYmILpp/9Nlc/krB15s5n1MPNtn3yL0TI0tWp0WlwDCV7
oUm1SfIM0F1fXGFyFDcqwoIr6JCQgXk6XtTg31YhH1xgUIclUVdtHqmAwAbLdIhQ
GAiHn2kCgYEAwD4pZ8HfpiOG/EHNoWsMATc/5yC7O8F9WbvcHZQIymLY4v/7HKZb
VyOR6UQ5/O2cztSGIuKSF6+OK1C34lOyCuTSOTFrjlgEYtLIXjdGLfFdtOO8GRQR
akVXdwuzNAjTBaH5eXbG+NKcjmCvZL48dQVlfDTVulzFGbcsVTHIMQUCgYEA7IQI
FVsKnY3KqpyGqXq92LMcsT3XgW6X1BIIV+YhJ5AFUFkFrjrbXs94/8XyLfi0xBQy
efK+8g5sMs7koF8LyZEcAXWZJQduaKB71hoLlRaU4VQkL/dl2B6VFmAII/CsRCYh
r9RmDN2PF/mp98Ih9dpC1VqcCDRGoTYsd7jLalMCgYAMgH5k1wDaZxkSMp1S0AlZ
0uP+/evvOOgT+9mWutfPgZolOQx1koQCKLgGeX9j6Xf3I28NubpSfAI84uTyfQrp
FnRtb79U5Hh0jMynA+U2e6niZ6UF5H41cQj9Hu+qhKBkj2IP+h96cwfnYnZFkPGR
kqZE65KyqfHPeFATwkcImQKBgCdrfhlpGiTWXCABhKQ8s+WpPLAB2ahV8XJEKyXT
UlVQuMIChGLcpnFv7P/cUxf8asx/fUY8Aj0/0CLLvulHziQjTmKj4gl86pb/oIQ3
xRRtNhU0O+/OsSfLORgIm3K6C0w0esregL/GMbJSR1TnA1gBr7/1oSnw5JC8Ab9W
injHAoGAJT1MGAiQrhlt9GCGe6Ajw4omdbY0wS9NXefnFhf7EwL0es52ezZ28zpU
2LXqSFbtann5CHgpSLxiMYPDIf+er4xgg9Bz34tz1if1rDfP2Qrxdrpr4jDnrGT3
gYC2qCpvVD9RRUMKFfnJTfl5gMQdBW/LINkHtJ82snAeLl3gjQ4=
-----END RSA PRIVATE KEY-----

View file

@ -1,74 +0,0 @@
Key Value
lease_id pki/issue/example-dot-com/d8214077-9976-8c68-9c07-6610da30aea4
lease_duration 279359999
lease_renewable false
certificate -----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIUf+jhKTFBnqSs34II0WS1L4QsbbAwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzQxWhcNMjUw
MTA1MTAyODExWjAbMRkwFwYDVQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsZx0Svr82YJpFpIy4fJNW5fKA6B8mhxS
TRAVnygAftetT8puHflY0ss7Y6X2OXjsU0PRn+1PswtivhKi+eLtgWkUF9cFYFGn
SgMld6ZWRhNheZhA6ZfQmeM/BF2pa5HK2SDF36ljgjL9T+nWrru2Uv0BCoHzLAmi
YYMiIWplidMmMO5NTRG3k+3AN0TkfakB6JVzjLGhTcXdOcVEMXkeQVqJMAuGouU5
donyqtnaHuIJGuUdy54YDnX86txhOQhAv6r7dHXzZxS4pmLvw8UI1rsSf/GLcUVG
B+5+AAGF5iuHC3N2DTl4xz3FcN4Cb4w9pbaQ7+mCzz+anqiJfyr2nwIDAQABo4H1
MIHyMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUm++e
HpyM3p708bgZJuRYEdX1o+UwHwYDVR0jBBgwFoAUncSzT/6HMexyuiU9/7EgHu+o
k5swOwYIKwYBBQUHAQEELzAtMCsGCCsGAQUFBzAChh9odHRwOi8vMTI3LjAuMC4x
OjgyMDAvdjEvcGtpL2NhMCEGA1UdEQQaMBiCEGNlcnQuZXhhbXBsZS5jb22HBH8A
AAEwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovLzEyNy4wLjAuMTo4MjAwL3YxL3Br
aS9jcmwwDQYJKoZIhvcNAQELBQADggEBABsuvmPSNjjKTVN6itWzdQy+SgMIrwfs
X1Yb9Lefkkwmp9ovKFNQxa4DucuCuzXcQrbKwWTfHGgR8ct4rf30xCRoA7dbQWq4
aYqNKFWrRaBRAaaYZ/O1ApRTOrXqRx9Eqr0H1BXLsoAq+mWassL8sf6siae+CpwA
KqBko5G0dNXq5T4i2LQbmoQSVetIrCJEeMrU+idkuqfV2h1BQKgSEhFDABjFdTCN
QDAHsEHsi2M4/jRW9fqEuhHSDfl2n7tkFUI8wTHUUCl7gXwweJ4qtaSXIwKXYzNj
xqKHA8Purc1Yfybz4iE1JCROi9fInKlzr5xABq8nb9Qc/J9DIQM+Xmk=
-----END CERTIFICATE-----
issuing_ca -----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUb5id+GcaMeMnYBv3MvdTGWigyJ0wDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzI5WhcNMjYw
MjI2MDIyNzU5WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAOxTMvhTuIRc2YhxZpmPwegP86cgnqfT1mXxi1A7
Q7qax24Nqbf00I3oDMQtAJlj2RB3hvRSCb0/lkF7i1Bub+TGxuM7NtZqp2F8FgG0
z2md+W6adwW26rlxbQKjmRvMn66G9YPTkoJmPmxt2Tccb9+apmwW7lslL5j8H48x
AHJTMb+PMP9kbOHV5Abr3PT4jXUPUr/mWBvBiKiHG0Xd/HEmlyOEPeAThxK+I5tb
6m+eB+7cL9BsvQpy135+2bRAxUphvFi5NhryJ2vlAvoJ8UqigsNK3E28ut60FAoH
SWRfFUFFYtfPgTDS1yOKU/z/XMU2giQv2HrleWt0mp4jqBUCAwEAAaOBgTB/MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdxLNP/ocx
7HK6JT3/sSAe76iTmzAfBgNVHSMEGDAWgBSdxLNP/ocx7HK6JT3/sSAe76iTmzAc
BgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEA
wHThDRsXJunKbAapxmQ6bDxSvTvkLA6m97TXlsFgL+Q3Jrg9HoJCNowJ0pUTwhP2
U946dCnSCkZck0fqkwVi4vJ5EQnkvyEbfN4W5qVsQKOFaFVzep6Qid4rZT6owWPa
cNNzNcXAee3/j6hgr6OQ/i3J6fYR4YouYxYkjojYyg+CMdn6q8BoV0BTsHdnw1/N
ScbnBHQIvIZMBDAmQueQZolgJcdOuBLYHe/kRy167z8nGg+PUFKIYOL8NaOU1+CJ
t2YaEibVq5MRqCbRgnd9a2vG0jr5a3Mn4CUUYv+5qIjP3hUusYenW1/EWtn1s/gk
zehNe5dFTjFpylg1o6b8Ow==
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsZx0Svr82YJpFpIy4fJNW5fKA6B8mhxSTRAVnygAftetT8pu
HflY0ss7Y6X2OXjsU0PRn+1PswtivhKi+eLtgWkUF9cFYFGnSgMld6ZWRhNheZhA
6ZfQmeM/BF2pa5HK2SDF36ljgjL9T+nWrru2Uv0BCoHzLAmiYYMiIWplidMmMO5N
TRG3k+3AN0TkfakB6JVzjLGhTcXdOcVEMXkeQVqJMAuGouU5donyqtnaHuIJGuUd
y54YDnX86txhOQhAv6r7dHXzZxS4pmLvw8UI1rsSf/GLcUVGB+5+AAGF5iuHC3N2
DTl4xz3FcN4Cb4w9pbaQ7+mCzz+anqiJfyr2nwIDAQABAoIBAHR7fFV0eAGaopsX
9OD0TUGlsephBXb43g0GYHfJ/1Ew18w9oaxszJEqkl+PB4W3xZ3yG3e8ZomxDOhF
RreF2WgG5xOfhDogMwu6NodbArfgnAvoC6JnW3qha8HMP4F500RFVyCRcd6A3Frd
rFtaZn/UyCsBAN8/zkwPeYHayo7xX6d9kzgRl9HluEX5PXI5+3uiBDUiM085gkLI
5Cmadh9fMdjfhDXI4x2JYmILpp/9Nlc/krB15s5n1MPNtn3yL0TI0tWp0WlwDCV7
oUm1SfIM0F1fXGFyFDcqwoIr6JCQgXk6XtTg31YhH1xgUIclUVdtHqmAwAbLdIhQ
GAiHn2kCgYEAwD4pZ8HfpiOG/EHNoWsMATc/5yC7O8F9WbvcHZQIymLY4v/7HKZb
VyOR6UQ5/O2cztSGIuKSF6+OK1C34lOyCuTSOTFrjlgEYtLIXjdGLfFdtOO8GRQR
akVXdwuzNAjTBaH5eXbG+NKcjmCvZL48dQVlfDTVulzFGbcsVTHIMQUCgYEA7IQI
FVsKnY3KqpyGqXq92LMcsT3XgW6X1BIIV+YhJ5AFUFkFrjrbXs94/8XyLfi0xBQy
efK+8g5sMs7koF8LyZEcAXWZJQduaKB71hoLlRaU4VQkL/dl2B6VFmAII/CsRCYh
r9RmDN2PF/mp98Ih9dpC1VqcCDRGoTYsd7jLalMCgYAMgH5k1wDaZxkSMp1S0AlZ
0uP+/evvOOgT+9mWutfPgZolOQx1koQCKLgGeX9j6Xf3I28NubpSfAI84uTyfQrp
FnRtb79U5Hh0jMynA+U2e6niZ6UF5H41cQj9Hu+qhKBkj2IP+h96cwfnYnZFkPGR
kqZE65KyqfHPeFATwkcImQKBgCdrfhlpGiTWXCABhKQ8s+WpPLAB2ahV8XJEKyXT
UlVQuMIChGLcpnFv7P/cUxf8asx/fUY8Aj0/0CLLvulHziQjTmKj4gl86pb/oIQ3
xRRtNhU0O+/OsSfLORgIm3K6C0w0esregL/GMbJSR1TnA1gBr7/1oSnw5JC8Ab9W
injHAoGAJT1MGAiQrhlt9GCGe6Ajw4omdbY0wS9NXefnFhf7EwL0es52ezZ28zpU
2LXqSFbtann5CHgpSLxiMYPDIf+er4xgg9Bz34tz1if1rDfP2Qrxdrpr4jDnrGT3
gYC2qCpvVD9RRUMKFfnJTfl5gMQdBW/LINkHtJ82snAeLl3gjQ4=
-----END RSA PRIVATE KEY-----
private_key_type rsa

View file

@ -1,6 +0,0 @@
To rebuild the cert.pem within this folder run the following commands
```shell
$ openssl x509 -in cert.pem -signkey key.pem -x509toreq -out cert.csr
$ openssl x509 -req -in cert.csr -CA ../root/rootcacert.pem -CAkey ../root/rootcakey.pem -CAcreateserial -out cert.pem -days 9132 -sha256 -extensions v3_req -extfile <(echo "[v3_req]\nsubjectAltName=DNS:cert.example.com,IP:127.0.0.1")
```

View file

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDGTCCAgGgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBxMQowCAYDVQQDFAEqMQsw
CQYDVQQIEwJHQTELMAkGA1UEBhMCVVMxJTAjBgkqhkiG9w0BCQEWFnZpc2hhbG5h
eWFrdkBnbWFpbC5jb20xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFVmF1
bHQwHhcNMTYwMjI5MjE0NjE2WhcNMjEwMjI3MjE0NjE2WjBxMQowCAYDVQQDFAEq
MQswCQYDVQQIEwJHQTELMAkGA1UEBhMCVVMxJTAjBgkqhkiG9w0BCQEWFnZpc2hh
bG5heWFrdkBnbWFpbC5jb20xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMF
VmF1bHQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMfRkLfIGHt1r2jjnV0N
LqRCu3oB+J1dqpM03vQt3qzIiqtuQuIA2ba7TJm2HwU3W3+rtfFcS+hkBR/LZM+u
cBPB+9b9+7i08vHjgy2P3QH/Ebxa8j1v7JtRMT2qyxWK8NlT/+wZSH82Cr812aS/
zNT56FbBo2UAtzpqeC4eiv6NAgMBAAGjQDA+MAkGA1UdEwQCMAAwCwYDVR0PBAQD
AgXgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZI
hvcNAQEFBQADggEBAG2mUwsZ6+R8qqyNjzMk7mgpsRZv9TEl6c1IiQdyjaCOPaYH
vtZpLX20um36cxrLuOUtZLllG/VJEhRZW5mXWxuOk4QunWMBXQioCDJG1ktcZAcQ
QqYv9Dzy2G9lZHjLztEac37T75RXW7OEeQREgwP11c8sQYiS9jf+7ITYL7nXjoKq
gEuH0h86BOH2O/BxgMelt9O0YCkvkLLHnE27xuNelRRZcBLSuE1GxdUi32MDJ+ff
25GUNM0zzOEaJAFE/USUBEdQqN1gvJidNXkAiMtIK7T8omQZONRaD2ZnSW8y2krh
eUg+rKis9RinqFlahLPfI5BlyQsNMEnsD07Q85E=
-----END CERTIFICATE-----

View file

@ -1,74 +0,0 @@
Key Value
lease_id pki/root/generate/exported/7bf99d76-dd3e-2c5b-04ce-5253062ad586
lease_duration 315359999
lease_renewable false
certificate -----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUb5id+GcaMeMnYBv3MvdTGWigyJ0wDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzI5WhcNMjYw
MjI2MDIyNzU5WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAOxTMvhTuIRc2YhxZpmPwegP86cgnqfT1mXxi1A7
Q7qax24Nqbf00I3oDMQtAJlj2RB3hvRSCb0/lkF7i1Bub+TGxuM7NtZqp2F8FgG0
z2md+W6adwW26rlxbQKjmRvMn66G9YPTkoJmPmxt2Tccb9+apmwW7lslL5j8H48x
AHJTMb+PMP9kbOHV5Abr3PT4jXUPUr/mWBvBiKiHG0Xd/HEmlyOEPeAThxK+I5tb
6m+eB+7cL9BsvQpy135+2bRAxUphvFi5NhryJ2vlAvoJ8UqigsNK3E28ut60FAoH
SWRfFUFFYtfPgTDS1yOKU/z/XMU2giQv2HrleWt0mp4jqBUCAwEAAaOBgTB/MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdxLNP/ocx
7HK6JT3/sSAe76iTmzAfBgNVHSMEGDAWgBSdxLNP/ocx7HK6JT3/sSAe76iTmzAc
BgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEA
wHThDRsXJunKbAapxmQ6bDxSvTvkLA6m97TXlsFgL+Q3Jrg9HoJCNowJ0pUTwhP2
U946dCnSCkZck0fqkwVi4vJ5EQnkvyEbfN4W5qVsQKOFaFVzep6Qid4rZT6owWPa
cNNzNcXAee3/j6hgr6OQ/i3J6fYR4YouYxYkjojYyg+CMdn6q8BoV0BTsHdnw1/N
ScbnBHQIvIZMBDAmQueQZolgJcdOuBLYHe/kRy167z8nGg+PUFKIYOL8NaOU1+CJ
t2YaEibVq5MRqCbRgnd9a2vG0jr5a3Mn4CUUYv+5qIjP3hUusYenW1/EWtn1s/gk
zehNe5dFTjFpylg1o6b8Ow==
-----END CERTIFICATE-----
expiration 1.772072879e+09
issuing_ca -----BEGIN CERTIFICATE-----
MIIDPDCCAiSgAwIBAgIUb5id+GcaMeMnYBv3MvdTGWigyJ0wDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYwMjI5MDIyNzI5WhcNMjYw
MjI2MDIyNzU5WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAOxTMvhTuIRc2YhxZpmPwegP86cgnqfT1mXxi1A7
Q7qax24Nqbf00I3oDMQtAJlj2RB3hvRSCb0/lkF7i1Bub+TGxuM7NtZqp2F8FgG0
z2md+W6adwW26rlxbQKjmRvMn66G9YPTkoJmPmxt2Tccb9+apmwW7lslL5j8H48x
AHJTMb+PMP9kbOHV5Abr3PT4jXUPUr/mWBvBiKiHG0Xd/HEmlyOEPeAThxK+I5tb
6m+eB+7cL9BsvQpy135+2bRAxUphvFi5NhryJ2vlAvoJ8UqigsNK3E28ut60FAoH
SWRfFUFFYtfPgTDS1yOKU/z/XMU2giQv2HrleWt0mp4jqBUCAwEAAaOBgTB/MA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSdxLNP/ocx
7HK6JT3/sSAe76iTmzAfBgNVHSMEGDAWgBSdxLNP/ocx7HK6JT3/sSAe76iTmzAc
BgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEA
wHThDRsXJunKbAapxmQ6bDxSvTvkLA6m97TXlsFgL+Q3Jrg9HoJCNowJ0pUTwhP2
U946dCnSCkZck0fqkwVi4vJ5EQnkvyEbfN4W5qVsQKOFaFVzep6Qid4rZT6owWPa
cNNzNcXAee3/j6hgr6OQ/i3J6fYR4YouYxYkjojYyg+CMdn6q8BoV0BTsHdnw1/N
ScbnBHQIvIZMBDAmQueQZolgJcdOuBLYHe/kRy167z8nGg+PUFKIYOL8NaOU1+CJ
t2YaEibVq5MRqCbRgnd9a2vG0jr5a3Mn4CUUYv+5qIjP3hUusYenW1/EWtn1s/gk
zehNe5dFTjFpylg1o6b8Ow==
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA7FMy+FO4hFzZiHFmmY/B6A/zpyCep9PWZfGLUDtDuprHbg2p
t/TQjegMxC0AmWPZEHeG9FIJvT+WQXuLUG5v5MbG4zs21mqnYXwWAbTPaZ35bpp3
BbbquXFtAqOZG8yfrob1g9OSgmY+bG3ZNxxv35qmbBbuWyUvmPwfjzEAclMxv48w
/2Rs4dXkBuvc9PiNdQ9Sv+ZYG8GIqIcbRd38cSaXI4Q94BOHEr4jm1vqb54H7twv
0Gy9CnLXfn7ZtEDFSmG8WLk2GvIna+UC+gnxSqKCw0rcTby63rQUCgdJZF8VQUVi
18+BMNLXI4pT/P9cxTaCJC/YeuV5a3SaniOoFQIDAQABAoIBAQCoGZJC84JnnIgb
ttZNWuWKBXbCJcDVDikOQJ9hBZbqsFg1X0CfGmQS3MHf9Ubc1Ro8zVjQh15oIEfn
8lIpdzTeXcpxLdiW8ix3ekVJF20F6pnXY8ZP6UnTeOwamXY6QPZAtb0D9UXcvY+f
nw+IVRD6082XS0Rmzu+peYWVXDy+FDN+HJRANBcdJZz8gOmNBIe0qDWx1b85d/s8
2Kk1Wwdss1IwAGeSddTSwzBNaaHdItZaMZOqPW1gRyBfVSkcUQIE6zn2RKw2b70t
grkIvyRcTdfmiKbqkkJ+eR+ITOUt0cBZSH4cDjlQA+r7hulvoBpQBRj068Toxkcc
bTagHaPBAoGBAPWPGVkHqhTbJ/DjmqDIStxby2M1fhhHt4xUGHinhUYjQjGOtDQ9
0mfaB7HObudRiSLydRAVGAHGyNJdQcTeFxeQbovwGiYKfZSA1IGpea7dTxPpGEdN
ksA0pzSp9MfKzX/MdLuAkEtO58aAg5YzsgX9hDNxo4MhH/gremZhEGZlAoGBAPZf
lqdYvAL0fjHGJ1FUEalhzGCGE9PH2iOqsxqLCXK7bDbzYSjvuiHkhYJHAOgVdiW1
lB34UHHYAqZ1VVoFqJ05gax6DE2+r7K5VV3FUCaC0Zm3pavxchU9R/TKP82xRrBj
AFWwdgDTxUyvQEmgPR9sqorftO71Iz2tiwyTpIfxAoGBAIhEMLzHFAse0rtKkrRG
ccR27BbRyHeQ1Lp6sFnEHKEfT8xQdI/I/snCpCJ3e/PBu2g5Q9z416mktiyGs8ib
thTNgYsGYnxZtfaCx2pssanoBcn2wBJRae5fSapf5gY49HDG9MBYR7qCvvvYtSzU
4yWP2ZzyotpRt3vwJKxLkN5BAoGAORHpZvhiDNkvxj3da7Rqpu7VleJZA2y+9hYb
iOF+HcqWhaAY+I+XcTRrTMM/zYLzLEcEeXDEyao86uwxCjpXVZw1kotvAC9UqbTO
tnr3VwRkoxPsV4kFYTAh0+1pnC8dbcxxDmhi3Uww3tOVs7hfkEDuvF6XnebA9A+Y
LyCgMzECgYEA6cCU8QODOivIKWFRXucvWckgE6MYDBaAwe6qcLsd1Q/gpE2e3yQc
4RB3bcyiPROLzMLlXFxf1vSNJQdIaVfrRv+zJeGIiivLPU8+Eq4Lrb+tl1LepcOX
OzQeADTSCn5VidOfjDkIst9UXjMlrFfV9/oJEw5Eiqa6lkNPCGDhfA8=
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 6f:98:9d:f8:67:1a:31:e3:27:60:1b:f7:32:f7:53:19:68:a0:c8:9d

Some files were not shown because too many files have changed in this diff Show more