Skip to content

meldron/psonoci

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

231 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

psonoci

PSONO CI Client.

PSONO is a secure Open Source Password Manager, which can be self hosted by anyone so you have to trust no one.

psonoci allows a secure access to your psono passwords (and other values) within your CI process.

Usage

psonoci --help

psonoci 0.6.0
Bernd Kaiser
Psono CI Client (https://github.com/meldron/psonoci)

Usage: psonoci [OPTIONS] <COMMAND>

Commands:
  secret    Psono secret commands (/api-key-access/secret/)
  api-key   Psono api-key inspect (/api-key-access/inspect/)
  config    Config commands (create, save, pack,...)
  run       Spawns processes with environment vars from the api-keys secrets
  env-vars  Convenience commands on environment variable secrets
  totp      TOTP commands
  ssh       SSH commands
  gpg       GPG commands
  license   Prints psonoci's license
  help      Print this message or the help of the given subcommand(s)

Options:
      --api-key-id <API_KEY_ID>
          Api key as uuid [env: PSONO_CI_API_KEY_ID=]
      --api-secret-key-hex <API_SECRET_KEY_HEX>
          Api secret key as 64 byte hex string [env: PSONO_CI_API_SECRET_KEY_HEX=]
      --server-url <SERVER_URL>
          Url of the psono backend server [env: PSONO_CI_SERVER_URL=]
      --timeout <TIMEOUT>
          Connection timeout in seconds [env: PSONO_CI_TIMEOUT=] [default: 60]
      --max-redirects <MAX_REDIRECTS>
          Maximum numbers of redirects [env: PSONO_CI_MAX_REDIRECTS=] [default: 0]
      --use-native-tls
          Use native TLS implementation (for linux musl builds a vendored openssl is used)
      --danger-disable-tls-verification
          DANGER: completely disables all TLS (common name and certificate) verification. You should
          not use this. A better approach is just using plain http so there's no false sense of
          security (Psono secrets are still authenticated)
      --der-root-certificate-path <DER_ROOT_CERTIFICATE_PATH>
          Path to a DER encoded root certificate which should be added to the trust store [env:
          PSONO_CI_ADD_DER_ROOT_CERTIFICATE_PATH=]
      --pem-root-certificate-path <PEM_ROOT_CERTIFICATE_PATH>
          Path to a pem encoded root certificate which should be added to the trust store [env:
          PSONO_CI_ADD_PEM_ROOT_CERTIFICATE_PATH=]
      --config-packed <config_packed>
          psonci config as packed string [env: PSONO_CI_CONFIG_PACKED=]
  -c, --config-path <config_path>
          psonoci config path [env: PSONO_CI_CONFIG_PATH=]
  -h, --help
          Print help
  -V, --version
          Print version

Required Options

These three options must be supplied (and be in front of the subcommand):

Option Env var Type Required Default Description
--api-key-id PSONO_CI_API_KEY_ID UUID yes None The UUID of your API key
--api-secret-key-hex PSONO_CI_API_SECRET_KEY_HEX 64 byte hex string yes None Secret key used for decryption of the user's secret key
--server-url PSONO_CI_SERVER_URL URL yes None Address of the PSONO's backend server - e.g.: https://www.psono.pw/server

There are several more options, please use the help commands for more info.

psonoci now uses clap for command-line parsing. The canonical option and enum value spelling shown in help output is kebab-case (for example url-filter), but for backward compatibility the legacy snake_case forms (for example url_filter) are still accepted for secret value types.

Identity secrets are available through the same secret get interface as the other typed secrets. For example, psonoci secret get <uuid> identity-email returns the stored email address, while psonoci secret get <uuid> json includes the nested identity object in the JSON output.

Onboard

Since version 0.6.0 psonoci provides an onboard command to create a config interactively from a Psono account without manually copying the API key id and secret key.

The onboarding command uses Psono's device code authentication flow to authenticate in the browser and receive the list of API keys available to your account. You then select the API key to use, and psonoci writes the resulting config either to a file or to stdout.

psonoci does not persist the temporary authentication session used during onboarding.

Unlike the regular commands, onboarding does not require --api-key-id or --api-secret-key-hex. Only the server URL is needed, either from --server-url, an existing config, or the interactive prompt.

Write a TOML config file

psonoci --server-url https://www.psono.pw/server \
    onboard --path ./psonoci.toml

If the output file already exists, add --overwrite.

Print a packed config to stdout

psonoci --server-url https://www.psono.pw/server \
    onboard --stdout --format packed

This is useful when you want to export the config into a CI secret store instead of writing it to disk.

Check psonoci onboard --help for all options.

SSH

Since version 0.5 psonoci supports Psono's SSH sub command, which allows you to add SSH keys stored in your Psono vault to your SSH agent.

This feature is currently not available on Windows.

The SSH subcommand provides the following operation:

add

psonoci ssh add secret-id [OPTIONS]: adds an SSH key from a Psono secret to your SSH agent.

Options:

  • --ssh-auth-sock-path <PATH>: Path of the SSH_AUTH_SOCK (overwrites $SSH_AUTH_SOCK environment variable)
  • --key-passphrase <PASSPHRASE>: Optional passphrase which was used to encrypt the key
  • --key-lifetime <SECONDS>: Limit the key's lifetime by deleting it after the specified duration in seconds
  • --key-confirmation: Require explicit user confirmation for each private key operation using the key

The secret must be of type SSH Key and contain a private key. On Unix systems, if --ssh-auth-sock-path is not provided, the command will use the SSH_AUTH_SOCK environment variable.

GPG

Since version 0.5 psonoci supports Psono's GPG secret type, allowing you to securely manage GPG keys stored in your Psono vault for signing and verification operations.

The GPG subcommand provides two main operations:

sign

psonoci gpg sign secret-id [OPTIONS] [INPUT_FILE]: signs data using the GPG private key stored in the specified secret.

Options:

  • --input-file <PATH>: File to sign (if not provided, reads from stdin)
  • --output <PATH>: Write signature to file (if not provided, writes to stdout)
  • --armor: Output ASCII armored signature instead of binary

The secret must be of type GPG Key and contain a private key.

verify

psonoci gpg verify secret-id --signature <SIGNATURE_FILE> [OPTIONS] [INPUT_FILE]: verifies a signature using the GPG public key stored in the specified secret.

Options:

  • --input-file <PATH>: File to verify (if not provided, reads from stdin)
  • --signature <PATH>, -s <PATH>: Path to the signature file (required)
  • --quiet, -q: Do not print verification error
  • --verbose, -v: Print success message with signature details

Returns with exit code 0 if the signature is valid, otherwise displays an error and returns with exit code 1. When using --verbose, displays information about when the signature was created and by whom.

TOTP

Since version 0.4 psonoci supports Psono's Time-based one-time password (TOTP) secret type.

Besides the standard functionality to read and write the secret info (secret subcommand), psonoci also supports the creation and validation of tokens (both commands require a correctly configured system time).

get-token

psonoci totp get-token secret-id: returns a currently valid TOTP token.

validate-token

psonoci totp validate-token secret-id token: checks if a token is currently valid. Returns with exit code 0 if valid, otherwise displays an error and returns with exit code 1.

get-url

Also there is the option to export the token otpauth url with psonoci totp get-url secret-id.

Run With Protected Environments

psonoci can now inject environment variables from your secrets right into you programs!

First create a new secret of the type "Environment Variables":

create Environment Variables

Then add this secret to your api key

create api key with env vars

and afterwards run:

psonoci -c /path/to/config-staging.toml run -- ./my_backend.py --timeout 10

This command will execute ./my_backend.py and inject all environment variables of all secrets into the process:

#!/usr/bin/python3

# content of my_backend.py
import os
import sys

print("args: {}".format(sys.argv))
print("environment: {}".format(os.environ))

Would return:

args: ['my_backend.py', '--timeout', '60']
environment: environ({'db_host': 'staging.psono.pw', 'db_password': '5IYqNwDwB6pPSr2YTK5fW', 'db_username': 'staging'})

Environment Variable Convenience Commands (env-vars)

Since v0.3.0 psonoci supports the new env-vars sub command, which provides convenience functions to get/update or create environment variable names in a specific secret.

Both subcommands work only on secrets of the type environment variables. If they are used with another type of secret, psonoci will return an error.

get-or-create

psonoci env-vars get-or-create returns the environment variable value by name. If more than one environment variable have the same name/key, the first one will be returned. If there is no environment variable with that name, a new entry will be created with that name and a random value.

--danger-password-allowed-chars adjusts of the used characters in the generated value. If this option is not supplied, psonoci will create an alphanumeric string ([a-zA-Z0-9]).

The length of the newly created random value can set with --password-length. Please take notice that this length specifies the number of unicode characters (not bytes).

Example

psonoci -c psonoci.toml env-vars get-or-create \
    --password-length 10 \
    --danger-password-allowed-chars "πŸ™ˆπŸ™‰πŸ™ŠπŸ‘ΉπŸ¦€πŸ¦πŸ¦‘πŸ¦πŸ§πŸ¨πŸ©πŸŽ‚πŸ΄σ §σ ’σ ·σ ¬σ ³σ Ώ" \
    e6305462-1d5d-478c-90eb-03da80e85cff DB_PASSWORD

creates (for example) this string: πŸ΄σ §σ ’σ ·σ ¬σ ³σ ΏπŸ¦‘πŸ‘ΉπŸ¦‘πŸ™‰πŸ§πŸ¦‘πŸ΄σ §σ ’σ ·σ ¬σ ³σ ΏπŸ™ŠπŸ¦€

  • String length: 10
  • Byte length: 88

(Please don't use only these chars as --danger-password-allowed-chars)

update-or-create

psonoci env-vars update-or-create updates or creates environment variable value by name with the supplied value and then returns this value. If there is no environment variable with that name a new one is created. If there are more than one with the same name, only the first will be updated. If no new value is provided a random one will be created. The new value can be adjusted with --password-length and -danger-password-allowed-chars. Please see above.

Config

psonoci can also be configured with a config file or config string.

Config File

psonoci \
    --api-key-id 00000000-0000-0000-0000-000000000000 \
    --api-secret-key-hex 0000000000000000000000000000000000000000000000000000000000000000 \
    --server-url 'https://psono.pw/server' \
    config save /tmp/psonoci.toml

Creates the following config file at /tmp/psonoci.toml

version = "1"

[psono_settings]
api_key_id = "00000000-0000-0000-0000-000000000000"
api_secret_key_hex = "0000000000000000000000000000000000000000000000000000000000000000"
server_url = "https://psono.pw/server/"

[http_options]
timeout = 60
max_redirects = 0
use_native_tls = false
danger_disable_tls_verification = false

The config file then can be loaded with:

psonoci -c /path/to/config.toml config show

or be supplied by an environment variable

PSONO_CI_CONFIG_PATH="/path/to/config.toml" psonoci config show

Config String

If you don't want to use files to load the config there is also the option to load the config from a base58 encoded string which can be supplied as an environment variable.

psonoci \
    --api-key-id 00000000-0000-0000-0000-000000000000 \
    --api-secret-key-hex 0000000000000000000000000000000000000000000000000000000000000000 \
    --server-url 'https://psono.pw/server' \
    config pack

Returns this string :

5dtuTPxg1kDP3Qoz2HKbMxT4kDqTYxbUo8mxR9yEp7YNSYq6dP8Gv4ysoVAjW8qS2iYwEaRm9NxzpbSXuwwXL45aHLiWi8TBSee3KnitgJPGyiuGCREGibB2pVCPCVg1zb11TpsbKuzV3aGhqQyE1NJnYwo9qrVjw6P

which than can be used with:

psonoci \
    --config-packed="5dtuTPxg1kDP3Qoz2HKbMxT4kDqTYxbUo8mxR9yEp7YNSYq6dP8Gv4ysoVAjW8qS2iYwEaRm9NxzpbSXuwwXL45aHLiWi8TBSee3KnitgJPGyiuGCREGibB2pVCPCVg1zb11TpsbKuzV3aGhqQyE1NJnYwo9qrVjw6P" \
    config show

or

PSONO_CI_CONFIG_PACKED="5dtuTPxg1kDP3Qoz2HKbMxT4kDqTYxbUo8mxR9yEp7YNSYq6dP8Gv4ysoVAjW8qS2iYwEaRm9NxzpbSXuwwXL45aHLiWi8TBSee3KnitgJPGyiuGCREGibB2pVCPCVg1zb11TpsbKuzV3aGhqQyE1NJnYwo9qrVjw6P" psonoci config show

Supported secret types:

  • Website
  • Application
  • Note
  • Identity
  • GPGKey
  • Bookmark
  • Environment Variables
  • Credit Card
  • TOTP
  • SSH Key

Build

Rust native

If you have rust installed just run cargo build --release.

The current version is tested with Rust 1.94.0.

cross

cross (which uses docker) is used to cross compile psonoci to several architectures.

After you installed cross just run:

cross build --target aarch64-unknown-linux-musl --release

Cross.toml defines which docker images are used to compile the binary. The images itself are build with the Dockerfiles located in ./build_files.

Supported Architectures

  • x86_64-unknown-linux-gnu
  • x86_64-unknown-linux-musl
  • x86_64-pc-windows-msvc
  • x86_64-pc-windows-gnu
  • x86_64-apple-darwin
  • aarch64-apple-darwin
  • aarch64-unknown-linux-musl
  • armv7-unknown-linux-gnueabihf
  • armv7-unknown-linux-musleabihf

Sadly I have to drop support for armv7-unknown-linux-musleabihf until Rust is able to link against MUSL v1.2.2.

Falling back to MUSL <=1.1 is no longer an option because of CVE-2020-28928

Since version 0.4 the armv7-unknown-linux-musleabihf target is back!

Since version 0.4 the aarch64-apple-darwin target is also build and released.

Install

Download psonoci binary, make executable (chmod +x psonoci), and place into a directory which is part of your $PATH.

License

The MIT License

Copyright (c) 2020-2026 Bernd Kaiser

About

psono ci client

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages