Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Infisical falls back to the logged-in Infisical CLI user (`infisical login`)
when no token or machine identity credentials are configured. This requires
Infisical CLI 0.44.0 or newer, because older CLIs ignore `--domain` and could
hand over another instance's session. Without a terminal on stdin, the CLI
is stopped after 30 seconds instead of waiting for a browser login. A new
`?personal=true` URI option reads the user's personal overrides and makes
`secretspec set` write a personal override instead of the shared secret.
Earlier SecretSpec versions ignore `?personal=true` and write the shared
secret, so everyone using such an alias needs 0.22 or newer.

- Proton Pass refs accept `field` to read any field of an existing item, such
as `ref = { item = "test-item", field = "password" }` for a login's
password, a custom field, or `Section.field`. Refs with a `field` are
Expand Down
94 changes: 89 additions & 5 deletions docs/src/content/docs/providers/infisical.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ both Infisical Cloud and self-hosted instances.
| URI | `infisical://[host]/PROJECT_ID[?options]` |
| Access | Read and write; version-pinned references are read-only |
| Best for | Infisical Cloud or self-hosted Infisical deployments |
| Authentication | Universal Auth machine identity or access token |
| Authentication | Universal Auth machine identity or access token, or the Infisical CLI login (0.22+, Infisical CLI 0.44.0+) |
| Availability | SecretSpec 0.16+; requires the `infisical` build feature |
| Default storage | Key `{key}` in `{path}/{project}/{profile}` |

Expand All @@ -46,7 +46,8 @@ per folder rather than one per secret.
### Prerequisites

- An Infisical project
- A machine identity with access to it
- A machine identity or access token with access to it, or an Infisical CLI login (0.22+,
Infisical CLI 0.44.0+)
- Build with `--features infisical`

### Universal Auth machine identity
Expand All @@ -72,6 +73,54 @@ $ export INFISICAL_TOKEN=...
Service tokens are not supported: Infisical deprecated them in favour of
machine identities.

### Infisical CLI login

<VersionCompatibility version="0.22" />

Without any configured credentials, the provider uses the user logged in to the
[Infisical CLI](https://infisical.com/docs/cli/overview) 0.44.0 or newer:

```bash
$ infisical login --domain https://app.infisical.com

$ secretspec run --provider "infisical://app.infisical.com/7e2f1a4c-...?env=dev" -- npm start
```

The access token comes from the first source that is configured, so CI with
explicit credentials is unaffected:

1. `token`, or `INFISICAL_TOKEN`
2. `client_id` and `client_secret`, or `INFISICAL_CLIENT_ID` and `INFISICAL_CLIENT_SECRET`
3. The Infisical CLI session

For the last step SecretSpec runs:

```bash
infisical user get token --plain --silent --domain <endpoint>
```

SecretSpec runs it at most once at a time per instance and reuses the token until it expires;
callers resolving in parallel share that run and its result. A failed attempt is not remembered,
so a long-running `secretspec serve` picks up a login made after the failure.

`<endpoint>` is the instance the URI names, e.g. `https://app.infisical.com`. Infisical CLI 0.44.0
and newer refuse to hand over a session issued by a different instance, so log in against the same
one (`infisical login --domain <endpoint>`). Older CLIs ignore `--domain` and would hand over
another instance's session, so SecretSpec checks `infisical --version` first and refuses a CLI
older than 0.44.0, including its pre-releases, or one whose version it cannot read.
`INFISICAL_PROFILE` and `INFISICAL_ORG` (Infisical CLI 0.44.0+) select which CLI login and
organization are used; they reach the CLI through the environment.

When SecretSpec's standard input is a terminal, it is passed to the CLI, so an expired session
can start the CLI's own browser login, or its prompt to paste a token, with its prompts on stderr.
Otherwise, as in CI, agents, or pipes, the CLI gets no input and is stopped after 30 seconds with
an error saying the session is missing or expired: run `infisical login --domain <endpoint>`
interactively, or configure a token or machine identity.
Set `SECRETSPEC_INFISICAL_PATH` when the binary is not `infisical` on `PATH`.

A half-configured machine identity — only `client_id` or only `client_secret` — is still an error
rather than a reason to fall back to the CLI login.

### Credentials from another provider

A machine identity's credentials can live in another store rather than in the
Expand All @@ -89,8 +138,9 @@ client_secret = "keyring"

The provider declares `client_id` and `client_secret` for Universal Auth, and
`token` for a ready-made access token. Each falls back to its corresponding
environment variable when it is not declared. Use
`secretspec config provider login infisical` to store declared credentials.
environment variable when it is not declared; with none of them set, the
provider falls back to the [Infisical CLI login](#infisical-cli-login) (0.22+).
Use `secretspec config provider login infisical` to store declared credentials.

## Provider credentials

Expand All @@ -101,7 +151,7 @@ environment variable when it is not declared. Use
### URI format

```
infisical://[host]/{project-id}[?env=slug&path=/prefix&tls=false]
infisical://[host]/{project-id}[?env=slug&path=/prefix&tls=false&personal=true]
```

- `host`: the Infisical instance (falls back to `INFISICAL_DOMAIN`, then the legacy
Expand All @@ -110,6 +160,8 @@ infisical://[host]/{project-id}[?env=slug&path=/prefix&tls=false]
- `?env=`: environment slug. Without it, the SecretSpec profile names the environment
- `?path=`: folder prefix holding SecretSpec's secrets (default: `/secretspec`)
- `?tls=false`: disable TLS, for self-hosted instances served over plain HTTP
- `?personal=true` (0.22+): read your personal overrides and write personal overrides (see
[Personal overrides](#personal-overrides))

Infisical's API addresses a project by UUID, not by the slug shown in its UI.

Expand Down Expand Up @@ -261,6 +313,38 @@ $ secretspec run --provider "infisical:///7e2f1a4c-..." -- npm start
Infisical's legacy `INFISICAL_API_URL` is honoured too, so an instance already configured for
their CLI works unchanged. `INFISICAL_DOMAIN` wins when both are set, matching the CLI.

### Personal overrides

<VersionCompatibility version="0.22" />

Infisical lets a user override a shared secret with a personal value only they see. With
`?personal=true`, reads return your personal override where one exists and the shared value
otherwise, and `secretspec set` writes a personal override instead of changing the shared secret.

```toml
[providers]
infisical = "infisical://app.infisical.com/7e2f1a4c-...?env=dev"
infisical_me = "infisical://app.infisical.com/7e2f1a4c-...?env=dev&personal=true"
```

```bash
$ secretspec set DATABASE_URL --provider infisical_me
```

- Infisical keeps personal overrides for users only, so this needs a user's token: the
[Infisical CLI login](#infisical-cli-login) or a user's `INFISICAL_TOKEN`. A machine identity
reads shared values only, and its personal writes are refused.
- A shared secret with the same key must already exist in the folder. Create it first through an
alias without `?personal=true`; a personal write never creates folders.
- Version-pinned refs read the shared secret's history.
- Requires an Infisical version with personal overrides on its v4 API.

:::caution[Pin teammates to SecretSpec 0.22+]
SecretSpec before 0.22 ignores `personal=true`: it reads the shared value and `secretspec set`
overwrites the team's shared secret instead of writing a personal override. Make sure everyone
using a manifest with a `personal=true` alias runs SecretSpec 0.22 or newer.
:::

### Approval policies

A project under an approval policy turns a write into a change request: Infisical stores nothing
Expand Down
8 changes: 4 additions & 4 deletions docs/src/content/docs/reference/providers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ selects the null label

Available since SecretSpec 0.16.

**URI**: `infisical://[HOST]/PROJECT_ID[?env=SLUG][&path=/PREFIX][&tls=false]` - Stores secrets in Infisical
**URI**: `infisical://[HOST]/PROJECT_ID[?env=SLUG][&path=/PREFIX][&tls=false][&personal=true]` - Stores secrets in Infisical. `personal=true` (0.22+) reads and writes the user's personal overrides; SecretSpec before 0.22 ignores it and writes the shared secret, so pin teammates to 0.22+.

```text
infisical://app.infisical.com/7e2f1a4c-... # Infisical Cloud (US)
Expand All @@ -728,9 +728,9 @@ The project is Infisical's project **UUID** (Project Settings → Project ID); i
accept the project slug. Without a host, the provider reads `INFISICAL_DOMAIN`, then Infisical's
legacy `INFISICAL_API_URL`, then defaults to Infisical Cloud.

**Features**: Read/write, cloud sync, profiles, machine-identity (Universal Auth) or token auth, secret references, version-pinned refs
**Prerequisites**: An Infisical project, a machine identity with access to it, build with `--features infisical`
**Authentication**: `INFISICAL_CLIENT_ID` + `INFISICAL_CLIENT_SECRET` (Universal Auth), or a ready-made `INFISICAL_TOKEN`. Service tokens are not supported; Infisical deprecated them in favour of machine identities.
**Features**: Read/write, cloud sync, profiles, machine-identity (Universal Auth) or token auth, Infisical CLI login (0.22+), personal overrides (0.22+), secret references, version-pinned refs
**Prerequisites**: An Infisical project, a machine identity or access token with access to it, or an Infisical CLI login (0.22+, Infisical CLI 0.44.0+), build with `--features infisical`
**Authentication**: `INFISICAL_CLIENT_ID` + `INFISICAL_CLIENT_SECRET` (Universal Auth), or a ready-made `INFISICAL_TOKEN`. With neither configured, the logged-in Infisical CLI user's session is used (0.22+), via `infisical user get token --domain <endpoint>`; SecretSpec refuses Infisical CLIs older than 0.44.0, which ignore `--domain`. Without a terminal on stdin, the CLI is stopped after 30 seconds. Service tokens are not supported; Infisical deprecated them in favour of machine identities.
**Storage**: Secret `{key}` in folder `/secretspec/{project}/{profile}`, in the environment named by the profile (or by `?env=`). Keys are stored verbatim.

By default the SecretSpec profile names the Infisical environment, so a `production` profile reads
Expand Down
Loading
Loading