---
path: onboarding/devops-onboarding/cli-and-secret-injection.mdx
title: CLI and secret injection
sidebar_position: 4
slug: cli-and-secret-injection
pagination_next: null
pagination_prev: null
description: >-
  How to use passwork-cli for secret injection in scripts and pipelines: exec, get,
  update, and api modes, Docker image usage, environment variable setup, and
  security best practices.
keywords:
  - Passwork
  - CLI
  - passwork-cli
  - exec
  - get
  - update
  - secret injection
  - environment variables
  - Docker
  - CI/CD
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Passwork CLI is the primary tool for secret injection in shell scripts and CI/CD pipelines. It retrieves secrets from Passwork, decrypts them locally (handling CSE transparently), and makes them available as environment variables or standard output — without the secret ever appearing in shell history or script files.

---

## Installation

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="PyPI" label="PyPI">

  ```shell
  pip install passwork-python
  ```
  </TabItem>
  <TabItem className="tab-item-container" value="GitHub SSH" label="GitHub (SSH)">

  ```shell
  pip install git+ssh://git@github.com:passwork-me/passwork-python.git
  ```
  </TabItem>
  <TabItem className="tab-item-container" value="GitHub HTTPS" label="GitHub (HTTPS)">

  ```shell
  pip install git+https://github.com/passwork-me/passwork-python.git
  ```
  </TabItem>
</Tabs>

**Requirements:**
- Python 3.10+
- requests>=2.31.0,
- python-dotenv>=1.0.0
- cryptography>=42.0.0
- pbkdf2>=1.3

### Docker image

For containerized environments and CI/CD runners, use the official Docker image:

```shell
docker pull passwork/passwork-cli:latest
```

---

## Authentication environment variables

All CLI modes read credentials from environment variables. Set these before calling any `passwork-cli` command:

```shell
export PASSWORK_HOST="https://passwork.example.com"
export PASSWORK_TOKEN="<access_token>"
export PASSWORK_REFRESH_TOKEN="<refresh_token>"   # optional, enables auto-renewal
export PASSWORK_MASTER_KEY="<master_key>"          # required only if CSE is enabled
```

Alternatively, pass them as flags: `--host`, `--token`, `--refresh-token`, `--master-key`.

:::tip No CSE
If client-side encryption is disabled on your Passwork instance, omit `PASSWORK_MASTER_KEY` and `--master-key`. The CLI works without it.
:::

---

## Exec mode — inject secrets into a process

`exec` is the core mode for secret injection. It fetches the specified records, decrypts them, sets them as environment variables, and **runs the command you specify** with those variables in scope. The variables exist only for the duration of the process — they are never written to disk or shell history.

### Syntax

```shell
passwork-cli exec [selection parameters] command_to_execute
```

### Selection parameters

| Parameter | Description |
|-----------|-------------|
| `--password-id <id>` | Single item ID (or multiple comma-separated) |
| `--folder-id <id>` | All items from a folder (or multiple comma-separated folders) |
| `--vault-id <id>` | All items from a vault |
| `--tags <tag1,tag2>` | All items matching the given tags |

### Variable naming

The item's **name** becomes the environment variable name. Spaces and special characters are replaced with underscore `_`. Custom field names become their own variables.

Record named `POSTGRES_PASSWORD` with custom field `DB_HOST` → injects `POSTGRES_PASSWORD` and `DB_HOST`.

### Examples

Run a database migration with credentials from a folder:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  passwork-cli exec --folder-id "prod-databases-folder-id" \
    ./migrate.sh
  ```
  </TabItem>
</Tabs>

Run a command that needs specific DB credentials by item ID:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  passwork-cli exec --password-id "postgres-order-svc-id" \
    psql -h "$DB_HOST" -U "$DB_USER" -d orders
  ```
  </TabItem>
</Tabs>

Run a complex command with pipes (use `--cmd`):

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  passwork-cli exec --password-id "server-creds-id" \
    --cmd "ssh user@server 'journalctl -u app | tail -100' > errors.log"
  ```
  </TabItem>
</Tabs>

Fetch all production API credentials by tag:

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  passwork-cli exec --tags "production,external-api" \
    ./sync-integrations.sh
  ```
  </TabItem>
</Tabs>

---

## Get mode — retrieve a specific value

`get` decrypts a single field from an item and writes it to **stdout**. Use this when a script needs to capture a secret value into a variable.

```shell
passwork-cli get --password-id "<item_id>" [--field <field_name>]
```

Without `--field`, `get` returns the password field. With `--field`, it returns the named custom field.

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  # Store the value in a variable (does not appear in process list)
  DB_PASS=$(passwork-cli get --password-id "postgres-prod-id")

  # Get a specific custom field
  AWS_KEY=$(passwork-cli get --password-id "aws-creds-id" --field "AWS_SECRET_ACCESS_KEY")
  ```
  </TabItem>
</Tabs>

:::warning Avoid echoing secrets
Never `echo $DB_PASS` in scripts. Use the value directly in the command that needs it. Shell history and CI/CD logs capture command arguments — not environment variable values.
:::

---

## Update mode — rotate a secret value

`update` writes a new value to a specified field in an existing Passwork item. Use this in rotation scripts after updating the secret in the target system.

```shell
passwork-cli update --password-id "<item_id>" --password "<new_value>"
```

For custom fields:

```shell
passwork-cli update --password-id "<item_id>" \
  --field "AWS_SECRET_ACCESS_KEY" --value "<new_key>"
```

See [Secret rotation](./secret-rotation.mdx) for complete rotation workflows.

---

## API mode — raw API calls

`api` sends an arbitrary API request and returns the JSON response. Use it for operations not covered by the other modes, or to inspect Passwork data from scripts.

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="shell">

  ```shell
  # List all vaults
  passwork-cli api --method GET --endpoint "v1/vaults"

  # Get a specific item
  passwork-cli api --method GET --endpoint "v1/items/<item_id>"
  ```
  </TabItem>
</Tabs>

---

## Docker image

Use `passwork/passwork-cli:latest` in environments where installing Python packages is not practical.

<Tabs className="tabs-container">
  <TabItem className="tab-item-container" value="shell" label="One-shot">

  ```shell
  docker run --rm \
    -e PASSWORK_HOST="https://passwork.example.com" \
    -e PASSWORK_TOKEN="$PASSWORK_TOKEN" \
    -e PASSWORK_MASTER_KEY="$PASSWORK_MASTER_KEY" \
    -v "$(pwd)":/app -w /app \
    passwork/passwork-cli:latest \
    exec --folder-id "$SECRETS_FOLDER_ID" ./deploy.sh
  ```
  </TabItem>
  <TabItem className="tab-item-container" value="compose" label="Docker Compose">

  ```yaml
  services:
    deploy:
      image: passwork/passwork-cli:latest
      environment:
        PASSWORK_HOST: ${PASSWORK_HOST}
        PASSWORK_TOKEN: ${PASSWORK_TOKEN}
        PASSWORK_MASTER_KEY: ${PASSWORK_MASTER_KEY}
      volumes:
        - .:/app
      working_dir: /app
      command: exec --folder-id "${SECRETS_FOLDER_ID}" ./deploy.sh
  ```
  </TabItem>
</Tabs>

The Docker image runs as a non-root user. For CI/CD pipeline usage, see [CI/CD patterns](./cicd-patterns.mdx).

For full CLI documentation, see [CLI utility](https://passwork.pro/tech-guides/api-and-integrations/cli-utility/) and [Docker container for CLI](https://passwork.pro/tech-guides/api-and-integrations/docker-container-for-cli/).