Page
Library
Module
Module type
Parameter
Class
Class type
Source
passage
- store and manage access to shared secrets
apt install age
opam install . --deps-only
Building the project
make build
Running tests
make test
Multi-line secrets with comments:
<empty line>
possibly several lines of comments
without empty lines
<empty line>
secret until end of file
Multi-line secrets without comments:
<empty line>
<empty line>
secret until end of file
Single-line secrets with comments:
single-line secret
<empty line>
comments until end of file
Single-line secrets without comments:
single-line secret
The rationale for why we have 2 distinct secret formats for multi-line and single-line secrets (and not just multi-line secrets) is mainly for backward compatibility reasons since most of the existing secrets are of the "single-line secret" format.
passage get [-c, --clip] [-l, --line=LINE] [-q, --qrcode] [-s, --singleline] SECRET_NAME
SECRET_NAME
, excluding commentspassage secret [-c, --clip] [-l, --line=LINE] [-q, --qrcode] [-s, --singleline] SECRET_NAME
passage get
passage cat [-c, --clip] [-l, --line=LINE] [-q, --qrcode] SECRET_NAME
SECRET_NAME
, including commentspassage show SECRET_NAME
SECRET_NAME
, including comments. Behaves differently when used with PATHs, please check below.passage template TEMPLATE_FILE [TARGET_FILE]
TARGET_FILE
by substituting all secrets in TEMPLATE_FILE
Secrets in TEMPLATE_FILE
are denoted with the following format {{{subdir/secret_name}}}
. In particular, note the following:
secret_name
secret_name
must start with an alphanumeric character (either lowercase or uppercase), followed by 0 or more alphanumeric characters, underscores, hyphens, slashes, or dots (reference: template_lexer.ml)Example when substituting a single-line secret:
$ cat template_file
{
"non_secret_config1": "hello",
"sendgrid_api_key": "{{{sendgrid_api_key}}}",
"non_secret_config2": "bye",
}
$ passage get sendgrid_api_key
thesupersecretkey
the above is the sendgrid api key!
$ passage template template_file
{
"non_secret_config1": "hello",
"sendgrid_api_key": "thesupersecretkey",
"non_secret_config2": "bye",
}
Example when substituting a multi-line secret:
$ cat template_file
foo{{{multiline_secret}}}bar
$ passage get multiline_secret
comment_line 1
comment_line 2
secret_line 1
secret_line 2
$ passage template template_file target_file
$ cat target_file
foosecret_line 1
secret_line 2bar
passage subst [TEMPLATE_ARG]
similar to passage template, but you pass in a string template and the result is output to stdout
$ passage secret test/secret
unbelievable stuff
$ passage subst "This secret is {{{test/secret}}}"
This secret is unbelievable stuff
passage template-secrets [TEMPLATE_FILE]
Secrets' recipients are specified in the .keys
file in the immediately containing folder. The first time a folder is used, passage will create this file. If no recipients are specified, it falls back to the caller as the sole recipient based on the file referenced by $PASSAGE_IDENTITY
.
Recipients are not inherited from containing (parent) folders. Recipients in a folder can only be increased when added by the existing recipients.
All secrets in a given folder must share the same set of recipients.
passage edit-who SECRET_NAME
passage new SECRET_NAME
$EDITOR
and prompts.passage create SECRET_NAME
passage create
. E.g.:$ echo "secret" | passage create secret_folder/secret
passage edit SECRET_NAME
SECRET_NAME
using $EDITOR
passage replace SECRET_NAME
SECRET_NAME
's secret with the user input and keeps the comments. Use Ctrl+d twice to signal end of input.replace
on a secret that doesn't exist, it creates a new secret without comments (only in folders where the user is already a recipient)passage rm [--force] [--verbose] SECRET_NAME / passage delete [--force] [--verbose] SECRET_NAME
SECRET_NAME
pathSECRET_NAME
is the only secret in that folder, passage deletes the whole folderpassage list [PATH]
/ passage ls [PATH]
PATH
passage search PATTERN [PATH]
PATH
containing contents matching PATTERN
passage show [PATH]
PATH
in a tree-like formatcat
when used with secret names instead of a PATH. Doesn't take any arguments or flagspassage refresh [PATH]
PATH
per the recipients in the corresponding .keys filepassage who [PATH]
PATH
passage what RECIPIENT_NAME
RECIPIENT_NAME
has access toPASSAGE_DIR
passage
directory.PASSAGE_KEYS
passage
keys directory.PASSAGE_SECRETS
passage
secrets directory.PASSAGE_IDENTITY
.key
file that will be used by passage
PASSAGE_X_SELECTION
primary
, secondary
, or clipboard
(default).PASSAGE_CLIP_TIME
passage healthcheck
.keys
filepassage realpath [--verbose] [PATH]