> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.hoop.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Management

> Securely inject credentials into resource roles without exposing them to users

export const DataFlowAnimation = ({variant = 'general'}) => {
  const VARIANTS = {
    database: {
      title: 'postgres:prod · live queries',
      items: [{
        type: 'safe',
        label: 'SELECT name, dept FROM employees'
      }, {
        type: 'sensitive',
        label: '→ ssn: 123-45-6789',
        tag: 'SSN'
      }, {
        type: 'safe',
        label: 'UPDATE orders SET status=shipped'
      }, {
        type: 'sensitive',
        label: '→ email: j.smith@acme.com',
        tag: 'PII'
      }, {
        type: 'safe',
        label: 'SELECT count(*) FROM sessions'
      }, {
        type: 'sensitive',
        label: '→ ssn: 987-65-4321',
        tag: 'SSN'
      }]
    },
    phi: {
      title: 'ehr-db:prod · patient queries',
      items: [{
        type: 'safe',
        label: 'SELECT patient_id, visit_date'
      }, {
        type: 'sensitive',
        label: '→ diagnosis: Type 2 Diabetes',
        tag: 'PHI'
      }, {
        type: 'safe',
        label: 'GET /api/lab-results/4821'
      }, {
        type: 'sensitive',
        label: '→ ssn: 321-54-9876',
        tag: 'SSN'
      }, {
        type: 'safe',
        label: 'SELECT medication FROM rx_active'
      }, {
        type: 'sensitive',
        label: '→ mrn: MRN-00284719',
        tag: 'MRN'
      }]
    },
    financial: {
      title: 'payments-db:prod · transactions',
      items: [{
        type: 'safe',
        label: 'SELECT tx_id, amount, status'
      }, {
        type: 'sensitive',
        label: '→ card: 4532-8821-0093-4417',
        tag: 'PCI'
      }, {
        type: 'safe',
        label: 'GET /api/settlements/batch-429'
      }, {
        type: 'sensitive',
        label: '→ account: 0028-4719-882',
        tag: 'PII'
      }, {
        type: 'safe',
        label: 'SELECT balance FROM accounts'
      }, {
        type: 'sensitive',
        label: '→ routing: 021000021',
        tag: 'PII'
      }]
    },
    general: {
      title: 'network traffic · live',
      items: [{
        type: 'safe',
        label: 'SELECT name FROM users'
      }, {
        type: 'sensitive',
        label: '→ 123-45-6789',
        tag: 'SSN'
      }, {
        type: 'safe',
        label: 'GET /api/v1/health'
      }, {
        type: 'sensitive',
        label: '→ alice@corp.com',
        tag: 'PII'
      }, {
        type: 'safe',
        label: 'kubectl get pods -n prod'
      }, {
        type: 'sensitive',
        label: '→ 4532-XXXX-XXXX-8821',
        tag: 'PCI'
      }]
    }
  };
  const ITEM_DELAY = 650;
  const FLASH_DURATION = 500;
  const CYCLE_PAD = 1200;
  const config = VARIANTS[variant] || VARIANTS.general;
  const [cycle, setCycle] = useState(0);
  const [visibleSet, setVisible] = useState(new Set());
  const [flashSet, setFlash] = useState(new Set());
  const timers = useRef([]);
  function T(fn, ms) {
    const id = setTimeout(fn, ms);
    timers.current.push(id);
  }
  useEffect(() => {
    timers.current.forEach(clearTimeout);
    timers.current = [];
    setVisible(new Set());
    setFlash(new Set());
    config.items.forEach((item, i) => {
      const t = i * ITEM_DELAY;
      T(() => setVisible(s => new Set([...s, i])), t);
      if (item.type === 'sensitive') {
        T(() => setFlash(s => new Set([...s, i])), t + 180);
        T(() => setFlash(s => {
          const n = new Set(s);
          n.delete(i);
          return n;
        }), t + 180 + FLASH_DURATION);
      }
    });
    T(() => setCycle(c => c + 1), config.items.length * ITEM_DELAY + CYCLE_PAD);
    return () => timers.current.forEach(clearTimeout);
  }, [cycle, variant]);
  return <div className="df-root" aria-hidden="true">
      <div className="mock-container df-mock">
        {}
        <div className="mock-toolbar" style={{
    justifyContent: 'space-between'
  }}>
          <div style={{
    display: 'flex',
    gap: 6
  }}>
            <div className="mock-dot" /><div className="mock-dot" /><div className="mock-dot" />
          </div>
          <span className="df-title">{config.title}</span>
          <span style={{
    width: 48
  }} />
        </div>

        {}
        <div className="df-stream">
          {config.items.map((item, i) => {
    const show = visibleSet.has(i);
    const flash = flashSet.has(i);
    const sens = item.type === 'sensitive';
    return <div key={i} className={`df-row${show ? ' df-vis' : ''}${flash ? ' df-flash' : ''}${sens ? ' df-sens' : ''}`}>
                <span className="df-dot" />
                <span className="df-text">{item.label}</span>
                {item.tag && <span className="df-tag">{item.tag}</span>}
              </div>;
  })}
        </div>

        {}
        <div className="df-footer">
          <span className="df-pulse" />
          <span>No protections active</span>
        </div>
      </div>

      <style>{`
        .df-root { width: 100%; }
        .df-mock { border-radius: 12px; overflow: hidden; }
        .df-title { font-family: var(--mono); font-size: 11px; color: rgba(var(--sand-100-rgb),0.2); }

        .df-stream { padding: 10px 16px; display: flex; flex-direction: column; gap: 2px; min-height: 200px; }

        .df-row {
          display: flex; align-items: center; gap: 10px;
          padding: 5px 10px; border-radius: 4px;
          opacity: 0; transform: translateX(-8px);
          transition: opacity 0.3s ease, transform 0.3s ease, background 0.25s ease;
        }
        .df-row.df-vis { opacity: 1; transform: translateX(0); }
        .df-row.df-flash { background: rgba(var(--warm-gold-rgb),0.08); }

        .df-dot { width: 5px; height: 5px; border-radius: 50%; background: rgba(var(--sand-100-rgb),0.15); flex-shrink: 0; }
        .df-sens .df-dot { background: rgba(var(--warm-gold-rgb),0.4); }
        .df-flash .df-dot { background: var(--warm-gold); }

        .df-text { font-family: var(--mono); font-size: 12px; color: rgba(var(--sand-100-rgb),0.4); white-space: nowrap; }
        .df-sens .df-text { color: rgba(var(--sand-100-rgb),0.5); }
        .df-flash .df-text { color: rgba(var(--warm-gold-rgb),0.8); }

        .df-tag {
          font-family: var(--sans); font-size: 9px; font-weight: 600;
          text-transform: uppercase; letter-spacing: 0.05em;
          color: rgba(var(--warm-gold-rgb),0.5); background: rgba(var(--warm-gold-rgb),0.06);
          padding: 1px 6px; border-radius: 3px;
          opacity: 0; transition: opacity 0.3s ease;
        }
        .df-flash .df-tag { opacity: 1; }

        .df-footer {
          display: flex; align-items: center; gap: 7px;
          padding: 10px 16px; border-top: 1px solid rgba(var(--sand-100-rgb),0.06);
          font-family: var(--sans); font-size: 11px; color: rgba(var(--sand-100-rgb),0.2);
        }
        .df-pulse {
          width: 6px; height: 6px; border-radius: 50%;
          background: rgba(var(--sand-100-rgb),0.15);
          animation: df-p 2s ease-in-out infinite;
        }
        @keyframes df-p { 0%,100%{opacity:.5} 50%{opacity:1} }
      `}</style>
    </div>;
};

<div style={{background: 'linear-gradient(135deg, #111111 0%, #1A1A1A 35%, #2A2A2A 70%, #3A3A3A 100%)', borderRadius: 14, overflow: 'hidden', padding: 24, height: 350}}>
  <DataFlowAnimation />
</div>

## What You'll Accomplish

Secrets Management lets you connect to databases and servers without exposing credentials to users. Instead of sharing passwords, you can:

* Store credentials in HashiCorp Vault or AWS Secrets Manager
* Inject secrets at runtime so users never see the actual values
* Rotate credentials without updating resource role configs
* Audit who accessed what, without credential exposure

***

## How It Works

<Steps>
  <Step title="Store Secrets">
    Save credentials in your secrets provider (HashiCorp Vault or AWS Secrets Manager).
  </Step>

  <Step title="Reference in Resource Role">
    Configure the resource role's environment variables with a secret reference (for example, `_aws:my-secret:DB_PASSWORD`) instead of a literal value.
  </Step>

  <Step title="Runtime Resolution">
    When a user opens a session, the agent fetches the secret from the provider and injects it.
  </Step>

  <Step title="Secure Access">
    The user connects successfully without ever seeing the credential.
  </Step>
</Steps>

### What Users See

When a user connects to a database configured with secrets:

```bash theme={"dark"}
$ hoop connect prod-postgres
Connected to prod-postgres
psql>
```

They connect successfully, but never see the database password. The password is fetched from the secrets provider and injected by Hoop.

***

## Supported Providers

<CardGroup cols={2}>
  <Card title="HashiCorp Vault" icon="vault">
    Key/Value Secrets Engine, versions 1 and 2
  </Card>

  <Card title="AWS Secrets Manager" icon="aws">
    AWS-native key/value secrets
  </Card>

  <Card title="Env JSON" icon="code">
    Expand values from a JSON environment variable on the agent. CLI-only — kept for compatibility with older agents.
  </Card>
</CardGroup>

<Note>
  Provider credentials are read by the **agent**, so the provider's environment variables must be exposed on the machine running the agent — not on the gateway.
</Note>

Connecting to AWS? Instead of storing static credentials, a resource role can also use an **AWS IAM Role** (assume-role) as its connection method. See [RDS IAM Authentication](/setup/configuration/rds-iam-auth).

***

## Use Cases

### 1. Database Credentials

Store database passwords in your secrets provider instead of in the resource role config. The resource role references the secret, so the literal password never lives in Hoop.

### 2. API Keys

Inject API keys for application resource roles at runtime, so scripts and commands can authenticate without the key being visible to the user.

### 3. SSH Keys

Keep SSH private keys in the secrets provider and inject them only at session time, keeping them out of resource role configs.

***

## Credential Rotation

One of the biggest benefits of secrets management is seamless credential rotation:

<Steps>
  <Step title="Update Secret in Provider">
    Change the password in Vault or AWS Secrets Manager.
  </Step>

  <Step title="No Resource Role Changes Needed">
    Resource role configs reference the secret, not the value.
  </Step>

  <Step title="New Sessions Use the New Credential">
    Next time someone connects, the agent fetches and injects the new password.
  </Step>
</Steps>

### Rotation Best Practices

1. **Schedule regular rotations** - Monthly or quarterly
2. **Test after rotation** - Verify resource roles still work
3. **Keep previous version** - Some providers support versioning
4. **Audit access** - Check who accessed secrets recently

***

## Security Best Practices

<CardGroup cols={2}>
  <Card title="Least Privilege" icon="shield-check">
    Grant the agent only read access to the secrets it needs
  </Card>

  <Card title="Audit Logging" icon="clipboard-list">
    Enable audit logs on your secrets provider
  </Card>

  <Card title="Rotate Regularly" icon="rotate">
    Schedule regular credential rotation
  </Card>

  <Card title="Separate by Environment" icon="layer-group">
    Use different secrets for dev/staging/prod
  </Card>
</CardGroup>

### What NOT to Do

* Don't store secrets in resource role configs directly
* Don't share provider tokens with users
* Don't use the same credentials across environments
* Don't skip rotation because "it's working"

***

<Note>
  Ready to set it up? The [Secrets Management configuration guide](/setup/configuration/secrets-manager-configuration) covers the Web App flow and the per-provider reference syntax for HashiCorp Vault, AWS Secrets Manager, and Env JSON.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuration Guide" icon="gear" href="/setup/configuration/secrets-manager-configuration">
    Provider setup and reference syntax
  </Card>

  <Card title="Access Control" icon="lock" href="/learn/features/access-control">
    Control who can access resource roles
  </Card>

  <Card title="Session Recording" icon="video" href="/learn/features/session-recording">
    Audit all resource role activity
  </Card>

  <Card title="HashiCorp Vault" icon="vault" href="https://www.vaultproject.io/docs">
    Vault documentation
  </Card>
</CardGroup>
