npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agentsecretstore/cli

v1.0.0

Published

CLI for Agent Secret Store — the secure vault built for AI agents

Readme

ass — Agent Secret Store CLI

npm version License: MIT Node ≥18 Platform: macOS Linux Windows

The secure vault built for AI agents — controlled from your terminal.

Stop putting secrets in .env files. Stop copy-pasting API keys into CI/CD dashboards.
Store every credential in an envelope-encrypted vault, retrieve it with one command, and get a complete audit trail for free.

# 5 lines to your first secret
brew install agent-secret-store/tap/ass
ass login
ass secrets set production/OPENAI_API_KEY sk-proj-...
export OPENAI_API_KEY=$(ass secrets get production/OPENAI_API_KEY)
ass audit --namespace production

Contents


Install

Homebrew (macOS / Linux) — recommended

brew install agent-secret-store/tap/ass

npm (all platforms)

npm install -g @agentsecretstore/cli

Verify the installation:

ass --version
# ass/1.0.0 darwin-arm64 node-v22.x.x

npx — run without installing

npx @agentsecretstore/cli secrets get production/MY_KEY

Direct binary download

Download the pre-compiled binary for your platform from the latest GitHub release:

| Platform | Binary | |----------|--------| | macOS arm64 | ass-macos-arm64 | | macOS x64 | ass-macos-x64 | | Linux x64 | ass-linux-x64 | | Windows x64 | ass-win-x64.exe |

# macOS arm64 example
curl -Lo ass \
  https://github.com/Agent-Secret-Store/agent-secret-store/releases/latest/download/ass-macos-arm64
chmod +x ass
sudo mv ass /usr/local/bin/
ass --version

Verify with SHA256 checksums published in each release:

curl -sL https://github.com/Agent-Secret-Store/agent-secret-store/releases/latest/download/checksums.txt \
  | sha256sum --check --ignore-missing

Quick Start

1. Get your API key at agentsecretstore.com/signup.

2. Authenticate:

ass login
# Paste your API key when prompted — it is stored securely in ~/.assrc

3. Store a secret:

ass secrets set production/OPENAI_API_KEY sk-proj-abc123

4. Retrieve it:

ass secrets get production/OPENAI_API_KEY

5. Use it in a script:

export OPENAI_API_KEY=$(ass secrets get production/OPENAI_API_KEY)

That's it. The secret never lives in .env, never appears in git log, and every access is recorded in the audit trail.


Configuration

ass reads configuration from three sources, in priority order:

| Priority | Source | Description | |----------|--------|-------------| | 1 | CLI flags | --api-key, --api-url | | 2 | Environment variables | ASS_AGENT_KEY, ASS_API_URL | | 3 | ~/.assrc | Written by ass login |

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | ASS_AGENT_KEY | — | Your agent key (ask_agent_... or ask_live_...) | | ASS_API_URL | https://api.agentsecretstore.com | Override API endpoint | | ASS_NO_COLOR | — | Disable colour output (1 to enable) |

~/.assrc

Written automatically by ass login. Plain key=value format:

ASS_AGENT_KEY=ask_live_...
ASS_API_URL=https://api.agentsecretstore.com

Tip: In team environments or CI, prefer ASS_AGENT_KEY as an environment variable rather than committing an .assrc file.

Global Flags

These flags work with every command:

  --api-key <key>   Override ASS_AGENT_KEY
  --api-url <url>   Override ASS_API_URL
  --json            Machine-readable JSON output
  --no-color        Disable colour output
  --quiet           Suppress non-essential output (good for scripts)
  --verbose         Extra debugging output
  --version         Print version and exit
  --help, -h        Print help for the current command

Command Reference

auth

ass login

Authenticate interactively. Prompts for your API key and writes it to ~/.assrc.

ass login
# ┌  Agent Secret Store
# │
# ◆  API Key (will not be stored in shell history):
# │  ▏

ass logout

Remove saved credentials from ~/.assrc.

ass logout
# ✓ Logged out. Credentials removed from ~/.assrc

ass whoami

Print the currently authenticated identity and tenant.

ass whoami
# ┌ Authenticated
# │ Agent:  deploy-bot
# │ Tenant: acme-corp
# │ Plan:   Pro
# └

ass status

Check connectivity to the vault and print service health.

ass status
# ┌ Agent Secret Store
# │ API:     https://api.agentsecretstore.com ✓ reachable
# │ Auth:    ✓ valid
# │ Plan:    Pro (expires 2027-03-01)
# │ Secrets: 42 across 3 namespaces
# └

secrets

The core command group. All secret operations are logged to the audit trail.

ass secrets get <namespace/key>

Retrieve the value of a secret.

# Print the value
ass secrets get production/OPENAI_API_KEY

# Capture in a variable (value never appears in shell history)
KEY=$(ass secrets get production/OPENAI_API_KEY)

# JSON output with metadata
ass secrets get production/OPENAI_API_KEY --json
# {
#   "key": "OPENAI_API_KEY",
#   "namespace": "production",
#   "value": "sk-proj-...",
#   "secret_type": "api_key",
#   "access_tier": "standard",
#   "retrieved_at": "2026-03-14T13:00:00Z"
# }

Tip: Always capture secrets into variables, never let them appear as command arguments where they'd show up in ps aux.

ass secrets set <namespace/key> [value]

Store or update a secret. If [value] is omitted, reads from stdin — this keeps the secret out of your shell history entirely.

# Inline value (appears in shell history — avoid for sensitive secrets)
ass secrets set staging/DEBUG_KEY abc123

# From stdin — RECOMMENDED for sensitive values
echo "sk-proj-..." | ass secrets set production/OPENAI_API_KEY
# or
read -rs SECRET && echo "$SECRET" | ass secrets set production/OPENAI_API_KEY

# From a file
ass secrets set production/TLS_CERT < cert.pem

# With explicit type and access tier
ass secrets set production/DB_PASSWORD \
  --type db_credential \
  --tier sensitive
# → Sensitive-tier secrets require human approval before agents can read them

# Critical tier (requires approval for both read AND write)
ass secrets set production/ROOT_CA_PRIVATE_KEY \
  --type ssh_key \
  --tier critical

--type options:

| Value | When to use | |-------|-------------| | api_key | Third-party API keys (OpenAI, Stripe, Twilio, etc.) | | oauth_token | OAuth access/refresh tokens | | db_credential | Database connection strings and passwords | | ssh_key | SSH private keys and certificates | | certificate | TLS certificates and PEM bundles | | custom | Everything else |

--tier options:

| Value | Behaviour | |-------|-----------| | standard | Agent can read immediately — no approval needed | | sensitive | Human approval required for agent reads | | critical | Human approval required for reads AND writes |

ass secrets list [namespace]

List all secrets in a namespace. Values are never shown.

# List all secrets in the production namespace
ass secrets list production

# ┌─────────────────────────────────────────────────────────┐
# │ Namespace: production                          3 secrets │
# ├──────────────────┬──────────────┬──────────┬────────────┤
# │ Key              │ Type         │ Tier     │ Updated    │
# ├──────────────────┼──────────────┼──────────┼────────────┤
# │ DATABASE_URL     │ db_credential│ sensitive│ 2026-03-10 │
# │ OPENAI_API_KEY   │ api_key      │ standard │ 2026-03-12 │
# │ STRIPE_KEY       │ api_key      │ sensitive│ 2026-03-14 │
# └──────────────────┴──────────────┴──────────┴────────────┘

# Nested namespace
ass secrets list staging/openai

# JSON for scripting
ass secrets list production --json | jq '[.secrets[].key]'

ass secrets delete <namespace/key>

Permanently delete a secret. Irreversible.

ass secrets delete staging/OLD_API_KEY
# ◇ Delete staging/OLD_API_KEY? This cannot be undone.
#   yes / no

# Skip confirmation in scripts
ass secrets delete staging/OLD_API_KEY --yes

ass secrets rotate <namespace/key>

Trigger rotation for a secret. For supported types (API keys with rotation APIs configured), the vault generates a new value. For others, the secret is flagged rotation-pending and you are notified.

ass secrets rotate production/STRIPE_KEY
# ✓ Rotation triggered for production/STRIPE_KEY
#   The new value will be available within ~30 seconds.
#   Downstream notification webhooks have been fired.

env

Bulk import and export secrets as .env files.

ass env import <file> --namespace <ns>

Import all KEY=VALUE pairs from a .env file into a vault namespace.

# Import entire .env.production file
ass env import .env.production --namespace production

# Importing 3 secrets into production:
#   ✓ OPENAI_API_KEY
#   ✓ DATABASE_URL
#   ✓ STRIPE_KEY
# Done. You can now delete .env.production safely.

# Dry run — preview without writing
ass env import .env.production --namespace production --dry-run

# Don't overwrite existing secrets
ass env import .env.production --namespace production --no-overwrite

# Set access tier for all imported secrets
ass env import .env.production --namespace production --tier sensitive

ass env export <namespace> [--out <file>]

Export all secrets in a namespace as a .env file.

# Print to stdout
ass env export production

# Write to a file
ass env export production --out .env.production

# Export only specific keys
ass env export production --keys OPENAI_API_KEY,DATABASE_URL

# Export for use in Docker
ass env export production --format docker-env > docker.env
docker run --env-file docker.env my-image

agents

Manage agent identities on your tenant.

# List all agents
ass agents list

# Create a new agent
ass agents create --name "ci-deploy" --description "GitHub Actions deployment agent"
# ✓ Agent created
#   ID:      ci-deploy
#   Key:     ask_agent_...  ← SAVE THIS — shown once

# Revoke an agent (all its tokens are immediately invalidated)
ass agents revoke ci-deploy

approvals

Review and act on agent secret-access requests.

# List pending requests
ass approvals list

# ┌────────────────────────────────────────────────────────────────────────┐
# │ Pending Approvals                                               2 total │
# ├────────────────┬──────────────┬───────────────────────────────────────┤
# │ ID             │ Agent        │ Request                               │
# ├────────────────┼──────────────┼───────────────────────────────────────┤
# │ apr_abc123     │ deploy-bot   │ READ production/ROOT_CA_KEY           │
# │ apr_def456     │ scraper-bot  │ READ production/DATABASE_URL          │
# └────────────────┴──────────────┴───────────────────────────────────────┘

# Approve with reason (reason is logged to audit trail)
ass approvals approve apr_abc123 --reason "Scheduled cert renewal — pipeline verified"

# Deny with reason
ass approvals deny apr_def456 --reason "Unexpected access — investigate scraper-bot"

# Approve all pending (use with caution)
ass approvals approve --all --reason "Batch approval for deployment"

tokens

Manage scoped access tokens.

# List active tokens for your agent
ass tokens list

# Create a token with specific scopes
ass tokens create \
  --scopes "secrets:read:production/*" \
  --ttl 15m
# ✓ Token issued (expires in 15 minutes)
#   Bearer eyJhbGc...

# Create a write-scoped token
ass tokens create \
  --scopes "secrets:write:staging/DEPLOY_KEY" \
  --ttl 5m

# Revoke a token immediately
ass tokens revoke tok_abc123

audit

Query the immutable audit trail. Every secret read, write, rotation, and approval action is permanently logged.

# Last 50 events (default)
ass audit

# ┌──────────────────────────────────────────────────────────────────────────┐
# │ Audit Trail                             production · last 50 events      │
# ├─────────────────────┬─────────────┬────────────────────┬────────────────┤
# │ Timestamp           │ Agent       │ Action             │ Resource       │
# ├─────────────────────┼─────────────┼────────────────────┼────────────────┤
# │ 2026-03-14 13:00:02 │ deploy-bot  │ secret.read        │ OPENAI_API_KEY │
# │ 2026-03-14 12:45:11 │ scraper-bot │ secret.read.denied │ DATABASE_URL   │
# │ 2026-03-14 12:30:00 │ will        │ secret.write       │ STRIPE_KEY     │
# └─────────────────────┴─────────────┴────────────────────┴────────────────┘

# Filter by namespace
ass audit --namespace production

# Filter by agent
ass audit --agent deploy-bot

# Time range
ass audit --since 2026-03-01 --until 2026-03-14

# Filter by action type
ass audit --action secret.read

# JSON for log aggregation / SIEM
ass audit --namespace production --json \
  | jq '.events[] | select(.action == "secret.read.denied")'

CI/CD Integration

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      ASS_AGENT_KEY: ${{ secrets.ASS_AGENT_KEY }}
    steps:
      - uses: actions/checkout@v4

      - name: Install ass CLI
        run: npm install -g @agentsecretstore/cli

      - name: Load secrets from vault
        run: |
          # Secrets go to $GITHUB_ENV — masked in logs automatically
          echo "OPENAI_API_KEY=$(ass secrets get production/OPENAI_API_KEY)" >> "$GITHUB_ENV"
          echo "DATABASE_URL=$(ass secrets get production/DATABASE_URL)" >> "$GITHUB_ENV"
          echo "STRIPE_KEY=$(ass secrets get production/STRIPE_KEY)" >> "$GITHUB_ENV"

      - name: Deploy
        run: ./scripts/deploy.sh

Note: GitHub Actions masks values added to $GITHUB_ENV by matching against registered secrets. Store ASS_AGENT_KEY as a repository or organisation secret — the CLI handles retrieving all other secrets dynamically.

GitLab CI

# .gitlab-ci.yml
deploy:
  stage: deploy
  image: node:22-alpine
  before_script:
    - npm install -g @agentsecretstore/cli
    - |
      export OPENAI_API_KEY=$(ass secrets get production/OPENAI_API_KEY)
      export DATABASE_URL=$(ass secrets get production/DATABASE_URL)
  script:
    - ./scripts/deploy.sh
  variables:
    ASS_AGENT_KEY: $ASS_AGENT_KEY  # set in GitLab CI/CD variables

Docker / docker compose

# Pass secrets to a container at runtime — never bake them into images
docker run \
  -e OPENAI_API_KEY="$(ass secrets get production/OPENAI_API_KEY)" \
  -e DATABASE_URL="$(ass secrets get production/DATABASE_URL)" \
  my-image:latest

With docker compose:

# Export a namespace to a temporary .env file, run compose, then delete it
ass env export production --out /tmp/.env.production
docker compose --env-file /tmp/.env.production up
rm /tmp/.env.production

Kubernetes / Helm

# Create a Kubernetes secret from vault contents
kubectl create secret generic app-secrets \
  --from-literal=OPENAI_API_KEY="$(ass secrets get production/OPENAI_API_KEY)" \
  --from-literal=DATABASE_URL="$(ass secrets get production/DATABASE_URL)"

Or use a Helm pre-install hook:

# templates/secrets-job.yaml (runs before app deployment)
apiVersion: batch/v1
kind: Job
metadata:
  name: populate-secrets
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
spec:
  template:
    spec:
      containers:
        - name: populate
          image: node:22-alpine
          command:
            - sh
            - -c
            - |
              npm install -g @agentsecretstore/cli
              kubectl create secret generic app-secrets \
                --from-literal=OPENAI_API_KEY="$(ass secrets get production/OPENAI_API_KEY)" \
                --save-config --dry-run=client -o yaml | kubectl apply -f -
          env:
            - name: ASS_AGENT_KEY
              valueFrom:
                secretKeyRef:
                  name: ass-credentials
                  key: ASS_AGENT_KEY

Piping & Scripting

ass is designed to be composable. Use --quiet or --json to suppress decorative output.

Pipe secret value directly to another program

# Feed a certificate to curl without writing it to disk
ass secrets get production/TLS_CERT | curl \
  --cert /dev/stdin \
  https://internal.example.com/api

# Decode and pipe a base64-encoded key
ass secrets get production/BASE64_KEY | base64 -d > /tmp/key.bin

# Use in a heredoc
psql "$(ass secrets get production/DATABASE_URL)" << 'SQL'
  SELECT COUNT(*) FROM users WHERE created_at > NOW() - INTERVAL '7 days';
SQL

Bulk operations with jq

# List all secrets, then retrieve values for specific keys
ass secrets list production --json \
  | jq -r '.secrets[].key' \
  | grep "OPENAI\|ANTHROPIC" \
  | while read key; do
      echo "$key=$(ass secrets get "production/$key")"
    done >> .env.ai

# Find all sensitive-tier secrets
ass secrets list production --json \
  | jq '.secrets[] | select(.access_tier == "sensitive") | .key'

# Count secrets per namespace
ass secrets list --json \
  | jq '.namespaces | to_entries[] | {namespace: .key, count: (.value | length)}'

Audit log analysis

# Alert on denied access (send to Slack webhook)
DENIED=$(ass audit --namespace production --action secret.read.denied --since 1h --json \
  | jq '.events | length')

if [ "$DENIED" -gt 0 ]; then
  curl -s -X POST "$SLACK_WEBHOOK" \
    -H "Content-Type: application/json" \
    -d "{\"text\": \"⚠️ ${DENIED} denied secret access attempt(s) in the last hour\"}"
fi

# Export audit log to CSV for compliance
ass audit --since 2026-01-01 --json \
  | jq -r '.events[] | [.timestamp, .agent_id, .action, .resource] | @csv' \
  > audit-q1-2026.csv

Secret rotation script

#!/usr/bin/env bash
# scripts/rotate-api-key.sh
set -euo pipefail

NAMESPACE="${1:?Usage: $0 <namespace> <key>}"
KEY="${2:?Usage: $0 <namespace> <key>}"

echo "Rotating ${NAMESPACE}/${KEY}..."
ass secrets rotate "${NAMESPACE}/${KEY}"

# Wait for rotation to complete
sleep 5

# Verify the new key works (example: OpenAI)
NEW_KEY=$(ass secrets get "${NAMESPACE}/${KEY}")
HTTP_STATUS=$(curl -sS -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer ${NEW_KEY}" \
  https://api.openai.com/v1/models)

if [ "$HTTP_STATUS" = "200" ]; then
  echo "✓ Rotation successful — new key is valid"
else
  echo "✗ New key validation failed (HTTP ${HTTP_STATUS}) — investigate immediately"
  exit 1
fi

Security Model

Envelope Encryption

Every secret is encrypted with a unique per-secret Data Encryption Key (DEK).
Every DEK is encrypted with your tenant's Key Encryption Key (KEK), managed in GCP KMS with HSM backing.

Secret value  ──AES-256-GCM──▶  Encrypted secret (Cloud SQL)
     │
  DEK (per-secret)
     │
  AES-256-GCM
     │
  KEK (per-tenant, GCP KMS HSM)

Scoped Token Flow

ass never uses your raw agent key for secret operations. On every secrets get:

  1. ass sends your agent key to /v1/tokens and requests a minimum-scope token
    (e.g., secrets:read:production/OPENAI_API_KEY)
  2. The API returns a short-lived signed JWT (15m default)
  3. ass uses that token for the actual secret retrieval
  4. The token is cached in-memory for its lifetime; your agent key never leaves the auth step
  5. The access is logged to the immutable audit trail

What ass Does NOT Do

  • Store secret values on disk
  • Log secret values anywhere
  • Send your agent key to any domain other than api.agentsecretstore.com
  • Cache secret values between invocations

Contributing

Contributions welcome! The CLI is in cli/src/ and written in TypeScript.

Development Setup

git clone https://github.com/Agent-Secret-Store/agent-secret-store
cd agent-secret-store/cli

npm install
npm run dev        # watch mode
npm run build      # production build
npm run typecheck  # type check without building
npm run test       # run tests

Project Structure

cli/src/
├── commands/
│   ├── agents/       # ass agents list|create|revoke
│   ├── approvals/    # ass approvals list|approve|deny
│   ├── audit/        # ass audit
│   ├── env/          # ass env import|export
│   ├── secrets/      # ass secrets get|set|list|delete|rotate
│   └── tokens/       # ass tokens list|create|revoke
├── init.ts           # ass login
├── login.ts          # auth helper
├── logout.ts
├── open.ts           # ass open (browser)
├── status.ts         # ass status
└── whoami.ts

Adding a Command

  1. Create cli/src/commands/mygroup/mycommand.ts
  2. Export a Command from commander
  3. Register it in cli/src/commands/mygroup/index.ts
  4. Add tests in cli/src/commands/mygroup/__tests__/

Testing

# Unit tests
npm run test

# Integration (requires ASS_AGENT_KEY pointing to a test tenant)
ASS_AGENT_KEY=ask_live_test_... npm run test:integration

Release

Releases are automated via the release-cli GitHub Actions workflow.
Bump the version, tag, and push:

npm version patch   # or minor / major
git push --follow-tags

The workflow builds binaries, creates a GitHub release, publishes to npm, and updates the Homebrew tap automatically.


Links