NHI Management
Machine Tokens
Machine tokens (secr_mt_) are purpose-built credentials for CI/CD pipelines, services, and automation. Unlike personal CLI tokens, machine tokens have lifecycle management, ownership tracking, environment hints, and optional conditional access rules.
Token Format
Machine tokens follow the format secr_mt_{env}_{hex}, where the environment hint (e.g. prod, ci) is embedded in the prefix for easy identification in logs and audits.
secr_mt_prod_a1b2c3d4e5f6...Tokens are hashed with SHA-256 before storage. The plaintext is shown only once at creation time.
Creating Tokens
# Create a token for production CI
secr token create --name "GitHub Actions prod" --env prod --expires 90d
# Create a non-expiring token (not recommended)
secr token create --name "Legacy deploy" --env ciPOST /v1/machine-tokens/:orgId
{
"name": "GitHub Actions prod",
"environmentHint": "prod",
"expiresInDays": 90,
"projectId": "uuid" // optional: scope to project
}The response includes the plaintext token. Store it securely — it cannot be retrieved again.
Lifecycle States
Machine tokens have four lifecycle states:
| State | Can Authenticate | Description |
|---|---|---|
| active | Yes | Normal operating state |
| disabled | No | Temporarily suspended — can be re-enabled |
| expired | No | Past its expiry date — must be rolled to a new token |
| revoked | No | Permanently deactivated — cannot be restored |
secr token disable <tokenId> # Temporarily suspend
secr token enable <tokenId> # Re-enable
secr token revoke <tokenId> # Permanently revokeRolling Tokens
Rolling generates a new token value while preserving the token's metadata, name, and access rules. The old token is immediately revoked.
secr token roll <tokenId>
# Output:
# ✓ Token rolled successfully
# New token: secr_mt_prod_f7e8d9c0b1a2...
# ⚠ Old token is now revoked. Update your CI/CD secrets.Ownership
Every machine token is assigned an owner (the creating user by default). When a team member is removed from the org, their tokens are flagged and can be transferred or revoked.
# List tokens with ownership info
secr token list
# Transfer ownership
secr token transfer <tokenId> --to user@example.comConditional Access
Add zero-trust rules to machine tokens: IP allowlists, time windows, and user-agent matching. Requests that don't match are rejected with a 403.
POST /v1/machine-tokens/:orgId
{
"name": "GitHub Actions",
"environmentHint": "ci",
"conditions": {
"ipAllowlist": ["140.82.112.0/20"],
"timeWindows": [{
"days": ["mon","tue","wed","thu","fri"],
"startUtc": "06:00",
"endUtc": "22:00"
}],
"userAgentPattern": "github-actions/*"
}
}| Condition | Description |
|---|---|
| ipAllowlist | Array of CIDR ranges — request IP must match at least one |
| timeWindows | Day-of-week + UTC hour ranges — requests outside windows are rejected |
| userAgentPattern | Glob pattern matched against the User-Agent header |
CI/CD Usage
Use machine tokens in your CI/CD pipeline by setting the SECR_TOKEN environment variable:
- name: Pull secrets
env:
SECR_TOKEN: ${{ secrets.SECR_TOKEN }}
run: npx @secr/cli pull --env productionpull-secrets:
script:
- npx @secr/cli pull --env production
variables:
SECR_TOKEN: $SECR_TOKENAPI Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /v1/machine-tokens/:orgId | Create token |
| GET | /v1/machine-tokens/:orgId | List tokens |
| GET | /v1/machine-tokens/:orgId/:tokenId | Get token details |
| PATCH | /v1/machine-tokens/:orgId/:tokenId | Update token |
| DELETE | /v1/machine-tokens/:orgId/:tokenId | Revoke token |
| POST | /v1/machine-tokens/:orgId/:tokenId/roll | Roll token |
| POST | /v1/machine-tokens/:orgId/:tokenId/disable | Disable token |
| POST | /v1/machine-tokens/:orgId/:tokenId/enable | Enable token |
| POST | /v1/machine-tokens/:orgId/:tokenId/transfer | Transfer ownership |
Secure your CI/CD pipeline
Replace long-lived secrets with managed machine tokens.