Skip to content
Open
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
19 changes: 17 additions & 2 deletions platform/credential-files.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
updated_at: October 26, 2026
updated_at: November 9, 2026
title: Credential Files
html_title: Write Credential Files Where Applications Expect Them
description: Configure where the Smallstep Agent writes a credential's key, certificate, and root CA, with per-file owners, modes, POSIX ACLs, and Windows access lists.
Expand Down Expand Up @@ -175,7 +175,7 @@ It requires `"protection": "NONE"` and `"store": "MACHINE"`.
| Field | Applies to | Values | Default |
| --- | --- | --- | --- |
| `path` | key, certificate, root | Absolute path in the platform's style | The agent's directory for the credential |
| `format` | key | `DEFAULT`, `PKCS8`, `CLASSIC`, `TSS2` | `DEFAULT` |
| `format` | key | `DEFAULT`, `PKCS8`, `CLASSIC`, `TSS2`, `PKCS12`, `PKCS12_LEGACY` | `DEFAULT` |
| `contents` | certificate | `CHAIN` (leaf and intermediates) or `LEAF` | `CHAIN` |
| `owner`, `group` | Linux, macOS | A name or a numeric ID, as a string | The agent's user and group |
| `mode` | Linux, macOS | Octal string, `"0000"` to `"0777"` | `"0640"`; `"0600"` for SSH user credentials |
Expand All @@ -184,6 +184,20 @@ It requires `"protection": "NONE"` and `"store": "MACHINE"`.
| `acl.entries` | Windows | List of `{principal, access}`, `access` one of `READ`, `MODIFY`, `FULL_CONTROL` | See [Windows defaults](#windows-defaults) |
| `key.windowsStore` | Windows | `false` keeps the credential out of the Windows stores | `true` |

With `PKCS12` or `PKCS12_LEGACY`, the key file is written as PKCS#8, and the agent also writes `service.p12`, a PKCS#12 bundle of the key, the certificate chain, and the root, with its password in `password.txt`.
Both are written in the agent's directory for the credential, even when `key.path` is set.
`PKCS12` encrypts the bundle with AES-256 and a SHA-256 MAC. `PKCS12_LEGACY` uses 3DES and a SHA-1 MAC, for apps that can't read the modern encryption.

The bundle and password file take the key file's permissions:

- **Linux and macOS:** the key's `owner`, `group`, `mode`, and `acl`.
- **Windows, with an `acl` on the key:** the key's access list, so an account the key grants can read them too.
- **Windows, without an `acl` on the key:** they inherit the permissions of the agent's folder for the credential, which grants only `SYSTEM` and `BUILTIN\Administrators`. That's the same access the key file's default list gives.

On Windows, only `SYSTEM` and the Administrators can list the agent's folder for the credential.
An account the key's `acl` grants can open `service.p12` and `password.txt` by their full paths, but can't browse the folder.
Configure the app with the full path to each file. A file picker, or a tool that lists the folder first, such as `type` in `cmd`, is denied.

The root CA is always written to its own file and never into the certificate file.
SSH credentials take `key` and `certificate` only.

Expand All @@ -194,6 +208,7 @@ The API refuses a credential that breaks these rules, with an error that names t
- **A custom key path needs a software key.** `key.path` is accepted only with `"protection": "NONE"` and without `key.pubFile`. The agent writes the key there and nowhere else.
- **Paths are absolute** in the platform's style (`/…` on Linux and macOS, `C:\…` or `\\server\share\…` on Windows), and distinct within a block.
- **Settings stay on their platform.** `owner`, `group`, and `mode` can't appear under `windows`, and a Windows access list can't appear under `linux` or `macos`. A block for an operating system the credential's `policy.operatingSystem` excludes is refused.
- **PKCS#12 needs a software key, and a machine key on Windows.** `"format": "PKCS12"` and `"PKCS12_LEGACY"` are accepted only with `"protection": "NONE"`. Under `windows`, they also need `"store": "MACHINE"`: a key in the user scope is held by the signed-in user's session, and the agent can't put it in a bundle.
- **`SYSTEM` keeps full control on Windows.** An access list that gives `SYSTEM` (`NT AUTHORITY\SYSTEM`, `S-1-5-18`) less than `FULL_CONTROL` is refused, and each principal can be listed once.

The API doesn't check owners, groups, or principals: they exist only on the device.
Expand Down
Loading