Passwords sent in a messenger or by email remain in the chat history. Response wrapping lets you send a short-lived one-time token instead of the secret: the secret can be retrieved with it only once, and an interception attempt is detectable.
Goal
Hand a password to a colleague so that it can be read only once, within a limited time, and so that the recipient can make sure the token was not replaced or used before them.
Prerequisites
To follow this example, you need:
- The sender has a Stronghold token with permission to read the secret being handed over or to
sys/wrapping/wrap. - The recipient can reach the Stronghold address. The recipient does not need to log in to Stronghold: the wrapping token itself is enough to unwrap.
- A separate communication channel for sending the token (messenger, email).
Step 1. Wrap the secret
Choose one of the options.
The secret is already stored in KV. Read it with the
-wrap-ttlflag:d8 stronghold kv get -wrap-ttl=1h -mount=secret handover/db-adminArbitrary data. Wrap it with
sys/wrapping/wrapwithout storing anything in KV:d8 stronghold write -wrap-ttl=1h sys/wrapping/wrap username=db-admin password='T3mp-P@ss'
The response contains the wrapping_token, wrapping_token_ttl, wrapping_token_creation_time, and wrapping_token_creation_path fields. Note the creation_path: the recipient will check it.
Choose the smallest sufficient -wrap-ttl: the shorter the lifetime, the smaller the interception window.
Step 2. Send the token
Pass the token and the creation path to the recipient through different channels:
- Send the
wrapping_tokento the recipient. - Separately (for example, by voice), tell them the expected creation path:
secret/data/handover/db-adminorsys/wrapping/wrap.
Step 3. Check the token (recipient)
Before unwrapping, check the token properties. This operation does not consume the token and does not require authentication:
d8 stronghold write sys/wrapping/lookup token=<WRAPPING_TOKEN><WRAPPING_TOKEN> is the wrapping token received from the sender.
Make sure that:
- the token exists and has not expired;
creation_pathmatches the one the sender told you;creation_timematches the time it was sent.
If the token is not found or the path does not match, do not unwrap it and report to your security team: the token may have been intercepted or replaced.
Step 4. Unwrap the secret (recipient)
Unwrap the secret with the wrapping token:
d8 stronghold unwrap <WRAPPING_TOKEN>The command returns the original response. After that, the token becomes invalid.
Verification
Check the result:
- Run
d8 stronghold unwrap <WRAPPING_TOKEN>again: the command must return an error because the token is single-use. - The sender checks that the token was used:
sys/wrapping/lookupfor this token returns an error. - With auditing enabled, find the
sys/wrapping/unwraprequest in the log and make sure it came from the expected recipient.
Mandatory wrapping for the handover directory
To prevent reading secrets from the handover/ directory without wrapping, set min_wrapping_ttl and max_wrapping_ttl in the policy used to read them:
d8 stronghold policy write handover-readers - <<'POLICY'
path "secret/data/handover/*" {
capabilities = ["read"]
min_wrapping_ttl = "1s"
max_wrapping_ttl = "24h"
}
POLICYGrant write access to the directory with a separate policy without these parameters.
For details, see Required response wrapping TTLs.
Cleanup
Delete the objects created in this example:
Delete the source secret if it is no longer needed:
d8 stronghold kv metadata delete -mount=secret handover/db-adminIf the recipient has not unwrapped the token and the handover is cancelled, revoke the token so that it cannot be used before its TTL expires:
d8 stronghold token revoke <WRAPPING_TOKEN>Ask the recipient to change the temporary password after the first login.