This is a standalone secrets backend plugin for use with HashiCorp Vault. It provisions Temporal Cloud service accounts and generates revocable, time-limited API keys as Vault dynamic secrets.
This README is intended for contributors who want to build, test, debug, or enhance the plugin. For implementation details, testing conventions, and the release process, see CONTRIBUTING.md.
Please note: We take security and our users' trust seriously. If you believe you have found a security issue, contact the repository maintainers privately rather than opening a public issue. Never include a Vault token, Temporal Cloud API key, or other credential in an issue, test fixture, or log attachment.
- Vault website
- Vault plugin documentation
- Vault plugin architecture
- Temporal Cloud documentation
- Temporal Cloud API key documentation
- Issue tracker
- Implementation decisions
- Contributing guide
This is an external Vault plugin and is meant to run with Vault. Development requires:
A Temporal Cloud account is not required for the unit tests. It is required only for the demo, acceptance tests, and propagation benchmark.
Clone the repository and run the fast test suite:
git clone https://github.com/ausmartway/vault-plugin-secrets-temporalcloud.git
cd vault-plugin-secrets-temporalcloud
go mod download
make testBuild the development binary:
make buildThe binary is written to bin/vault-plugin-secrets-temporalcloud. The build
target also prints the SHA256 Vault needs when registering that binary.
The plugin exposes these primary paths:
| Path | Purpose |
|---|---|
config |
Configure and validate the root Temporal Cloud API key. |
config/probe |
Configure API key propagation sampling. |
config/rotate-root |
Safely mint, verify, and install a replacement root key. |
service-accounts/<name> |
Create or manage a Temporal Cloud service account. |
creds/<name> |
Generate a Temporal Cloud API key under a Vault lease. |
For local development, start an in-memory Vault server with the current source
built, registered, and mounted at temporalcloud/:
make devIn another terminal, configure the Vault client and run the end-to-end demo:
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=root
export TEMPORAL_CLOUD_API_KEY="<service-account-api-key>"
./examples/demo.shThe demo uses real Temporal Cloud resources. It configures the backend, rotates and deletes the supplied bootstrap key, creates a service account, issues and revokes a leased API key, and deletes the service account. Read the demo walkthrough before running it.
Use Vault's built-in help to inspect the current schema while developing:
vault path-help temporalcloud/config
vault path-help temporalcloud/config/probe
vault path-help temporalcloud/service-accounts/example
vault path-help temporalcloud/creds/exampleMost backend behavior lives in the root package. Cloud Ops and Namespace gRPC
calls are isolated behind client.CloudOps in client/, allowing path handlers
to be tested without network access. See CONTRIBUTING.md for
the repository layout and test-double conventions.
Common development commands are:
make build # compile into ./bin and print the binary SHA256
make test # run credential-free unit tests
make dev # build and start a dev-mode Vault with the plugin mounted
make sweep # remove leaked vault-acctest-* resources
make release-check # validate the GoReleaser configuration
make snapshot # build unpublished release artifacts in ./distFormat changed Go files with gofmt. make lint runs golangci-lint when it
is installed.
Live development requires a Temporal Cloud API key owned by a dedicated service account. The recommended least-privilege identity combines the predefined Read-Only account role with a Custom Role granting these account-scoped actions:
cloud.apikey.create
cloud.apikey.get
cloud.apikey.list
cloud.apikey.delete
cloud.serviceaccount.create
cloud.serviceaccount.update
cloud.serviceaccount.delete
Read-Only supplies cloud.serviceaccount.get,
cloud.serviceaccount.list, and cloud.asyncoperation.get. Global Admin is a
supported fallback. Account Owner works but produces a least-privilege warning.
User-owned keys and unsupported service-account role combinations are rejected.
Export the root key before running the demo or acceptance tests:
export TEMPORAL_CLOUD_API_KEY="<service-account-api-key>"The key is displayed only once when created. Do not commit it to this repository or save it in shell scripts.
The live tooling recognizes these variables:
| Variable | Required | Purpose |
|---|---|---|
TEMPORAL_CLOUD_API_KEY |
Yes | Service-account-owned root credential. Vault derives its owner ID. |
TEMPORAL_CLOUD_ADDRESS |
No | Cloud Ops endpoint; defaults to saas-api.tmprl.cloud:443. |
TEMPORAL_CLOUD_TEST_NAMESPACE |
No | Namespace ID used by propagation tests. It must allow API key authentication. |
TEMPORAL_CLOUD_ALLOW_ROOT_ROTATION=1 |
Opt-in | Allows the destructive root-rotation acceptance test. |
TEMPORAL_CLOUD_RUN_CAPACITY_TEST=1 |
Opt-in | Allows the test that creates all 20 permitted keys. |
Use a dedicated test account where creating and deleting service accounts and
API keys is safe. Live tests name their resources vault-acctest-* so remnants
from an interrupted run can be identified and removed.
make dev is the fastest local setup. To configure the development plugin
manually, place the binary in Vault's configured plugin_directory, start
Vault, and register the binary in the
plugin catalog:
SHA=$(shasum -a 256 bin/vault-plugin-secrets-temporalcloud | cut -d' ' -f1)
vault plugin register \
-sha256="$SHA" \
-command="vault-plugin-secrets-temporalcloud" \
secret \
vault-plugin-secrets-temporalcloud
vault secrets enable \
-path=temporalcloud \
vault-plugin-secrets-temporalcloudRebuild and register a new checksum whenever the binary changes. Vault refuses to launch a plugin whose executable does not match the catalog checksum.
Configure the mounted backend and rotate away the bootstrap key:
vault write temporalcloud/config \
api_key="$TEMPORAL_CLOUD_API_KEY"
vault write -f temporalcloud/config/rotate-rootRoot rotation deletes the supplied key. Use a disposable bootstrap key, and do
not continue using TEMPORAL_CLOUD_API_KEY after rotation.
The default test suite uses in-memory Vault storage and stub Cloud Ops clients. It requires no credentials and makes no network calls:
make testRun an individual test while iterating:
go test . -run TestRotateRoot -count=1 -v
go test ./client -run TestProbe -count=1 -vBefore submitting a change, run:
make fmt
go test -race ./...
go vet ./...
git diff --checkTests that require the real API are protected by the acceptance build tag and
are not included in make test.
Acceptance tests create and delete real Temporal Cloud service accounts and API keys. Run them only against an account intended for development:
make test-liveThe root-rotation and 20-key capacity tests remain skipped unless their explicit
opt-in variables are set. A Namespace propagation test runs only when
TEMPORAL_CLOUD_TEST_NAMESPACE is set.
If a test process is interrupted, clean up resources named vault-acctest-*:
make sweepTo benchmark API key propagation independently of Vault:
go run ./cmd/propagation-benchmark \
-namespace <namespace.account> \
-trials 500 \
-interval 1m \
-poll-interval 100ms \
> propagation.csvThe benchmark creates and deletes real keys. Review its behavior and cleanup safeguards in CONTRIBUTING.md before running a long trial.
Search the issue tracker before opening a report. For reproducible bug reports, include:
- the plugin version or commit;
- the Vault and Go versions;
- the affected path and operation;
- the smallest safe reproduction;
- the expected and actual behavior; and
- sanitized logs or error messages.
State whether the problem reproduces in the unit suite, dev-mode Vault, or a real Temporal Cloud account. Remove API keys, Vault tokens, lease credentials, account IDs, and other sensitive values before posting.
This project is licensed under the MIT License. See LICENSE.