Metadata-Version: 2.4
Name: secretcarousel
Version: 2.0.0
Summary: Python SDK for SecretCarousel — the secret vault coding agents run themselves. Store, rotate, share, and hand off credentials via one-time claim tokens.
Author-email: jyswee <jyswee@gmail.com>
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://secretcarousel.com
Project-URL: Documentation, https://secretcarousel.com/docs/quickstart.html
Keywords: secrets,secret-management,api-client,vault,agent-first,ai-agents,claim-tokens,encryption,rotation
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# secretcarousel

Python SDK for **SecretCarousel** — the secret vault your coding agents run themselves. Store, rotate, and hand off credentials from any Python agent, so they stop passing keys in plain text.

## Install

```bash
pip install secretcarousel
```

## Quick Start

```python
from secretcarousel import SecretCarouselClient

sc = SecretCarouselClient(api_key="sc_...")

# Store a secret — AES-256-GCM encrypted at rest; returns an id, never echoes the value
secret = sc.create_secret(
    "DATABASE_URL",
    "postgres://user:pass@host/db",
    secret_type="database-credentials",
)

# Retrieve by id — decrypted on demand, access-logged
result = sc.get_secret(secret["secretId"])
print(result["value"])

# List / search — ids + names, never values
sc.list_secrets()
sc.search_secrets("stripe")

# Rotate now
sc.rotate_secret(secret["secretId"])
```

## Self-provision — no key, no human

An agent can bootstrap its own vault mid-session:

```python
sc = SecretCarouselClient.signup("my-project")
print(sc.api_key)  # save this — shown once
```

## Claim tokens — hand a secret to another agent

Mint a **one-time, scoped, expiring** token; another agent — different project,
even different company — redeems it exactly once, and the token burns. The
plain-text value never crosses the boundary as a copy-pasteable string, and
every mint/redeem lands in the audit trail.

```python
# Agent A: hand a secret to another tenant/agent
token = sc.create_claim(
    "<the-secret-value>",
    target_tenant_id="partner-tenant",
    contract_id="CTR-ID",
)

# Agent B: redeem the token you were handed (once, audited)
sc.redeem_claim(token["token"])

# List the tokens you've minted + their status
sc.list_claims()
```

## Sharing — time- and view-limited links for humans

```python
share = sc.create_share(secret["secretId"], expiration_hours=1, max_uses=1)
sc.list_shares()
```

## Environments — .env in, .env out

```python
sc.export_env(env="production")
sc.promote_secrets(from_env="staging", to_env="production")
```

## Features

- **Zero dependencies** — stdlib `urllib` only
- **Full type hints** — mypy compatible, ships `py.typed`
- **Secrets** — store, retrieve, update, delete; AES-256-GCM at rest; typed
- **Claim tokens** — one-time, scoped, expiring, audited cross-tenant handoff
- **Sharing** — time- and view-limited links
- **Rotation** — rotate now or check schedule/status
- **Environments** — export as `.env`, promote between environments
- **Audit trail** — immutable event log, exportable as CSV
- **Agent self-signup** — provision a vault with no key and no human

## API

| Method | Description |
|--------|-------------|
| `SecretCarouselClient.signup(tenant_id)` | Self-provision a vault, returns an authenticated client |
| `list_secrets(**query)` | List secrets (metadata only) |
| `search_secrets(q, **query)` | Search by name/tag/description |
| `get_secret(id)` | Get a secret with decrypted value |
| `create_secret(name, value, secret_type=None, **extra)` | Create a secret |
| `update_secret(id, **data)` | Update (creates a new version) |
| `delete_secret(id)` | Delete a secret |
| `rotate_secret(id, **options)` | Rotate now |
| `get_rotation_status(id)` | Rotation schedule + status |
| `create_share(secret_id, expiration_hours=None, max_uses=None)` | Create a share link |
| `list_shares(**query)` / `get_share(id)` | List / get shares |
| `revoke_share(id)` / `extend_share(id, **data)` | Revoke / extend a share |
| `access_share(token)` | Redeem a share link (consumes a view) |
| `create_claim(secret_value, target_tenant_id, contract_id, ...)` | Mint a claim token |
| `redeem_claim(token)` | Redeem a claim token (once, audited) |
| `list_claims(**query)` / `get_claim(id)` / `revoke_claim(id)` | Manage claim tokens |
| `export_env(**query)` / `promote_secrets(**data)` | Environment import/export |
| `get_audit_logs(**query)` / `export_audit_csv(**query)` | Audit trail |
| `create_backup(**data)` / `list_backups(**query)` | Backups |

All list/query methods accept keyword filters (e.g. `sc.list_secrets(limit=50)`).
Non-2xx responses raise a typed `SecretCarouselError` subclass
(`AuthenticationError`, `ForbiddenError`, `NotFoundError`, `ValidationError`).

## Links

- Quick Start: https://secretcarousel.com/docs/quickstart.html
- API Reference: https://secretcarousel.com/api
- CLI: https://www.npmjs.com/package/secretcarousel

## License

Proprietary — Tyga.Cloud Ltd. See LICENSE file.
