|
| 1 | +## Security |
| 2 | + |
| 3 | +> Follow these security guidelines for every change to the pyatlan SDK. |
| 4 | +
|
| 5 | +### Contact |
| 6 | + |
| 7 | +- **Security Team:** #bu-security-and-it on Slack |
| 8 | + |
| 9 | +### Quickstart for Agents |
| 10 | + |
| 11 | +atlan-python (pyatlan) is Atlan's Python SDK, providing typed wrappers around the Atlan REST API. Key modules: |
| 12 | + |
| 13 | +- `pyatlan/client/atlan.py` — `AtlanClient` (Pydantic `BaseSettings`); initialised with `base_url` and `api_key`; uses `httpx` with `PyatlanSyncTransport` / async variant; supports impersonation via `ImpersonationClient`. |
| 14 | +- `pyatlan/client/transport.py` — `PyatlanSyncTransport` and async variant wrap `httpx.HTTPTransport` with retry logic; `trust_env=True` by default to respect `HTTPS_PROXY` env. |
| 15 | +- `pyatlan/client/credential.py` — manages credential objects (Vault-stored secrets). |
| 16 | +- `pyatlan/client/token.py` — manages API tokens (long-lived service account keys). |
| 17 | +- `pyatlan/cache/` — caches for tags, groups, roles, custom metadata. |
| 18 | + |
| 19 | +Review every change for: |
| 20 | + |
| 21 | +- **API key logging** — `AtlanClient` holds `api_key` (set as `Authorization: Bearer <key>` on every request); it must never appear in log output, error messages, or exception tracebacks; wrap all `httpx` error handling to strip `Authorization` from logged request details; the `api_key` field must be excluded from any Pydantic model `dict()` / `model_dump()` used for logging. |
| 22 | +- **Impersonation token safety** — `ImpersonationClient` generates short-lived impersonation JWTs; these tokens must not be logged; the target user's identity (email/username) may be logged but not the token value. |
| 23 | +- **TLS verification** — `PyatlanSyncTransport` must never pass `verify=False` to `httpx.HTTPTransport`; if users need to use custom CA bundles, accept a path to the bundle, not a `False` flag. |
| 24 | +- **`base_url` validation** — `base_url` is validated as `HttpUrl` via Pydantic; ensure validation rejects non-HTTPS URLs in production builds (the `HttpUrl` type allows HTTP by default — add a validator if HTTPS is required). |
| 25 | +- **Proxy credential exposure** — `trust_env=True` means `HTTPS_PROXY` is honoured; proxy credentials embedded in the URL (e.g., `http://user:pass@proxy`) must not be echoed in log output; strip credentials from proxy URLs before logging. |
| 26 | +- **Credential object sensitivity** — `CredentialClient` returns objects with `username` and potentially `password` fields; these must not be logged; use repr/str exclusion for credential model classes. |
| 27 | + |
| 28 | +### Security Invariants |
| 29 | + |
| 30 | +- **[MUST]** `api_key` must never appear in log output, error messages, or exception tracebacks. |
| 31 | +- **[MUST]** Impersonation JWT values must not be logged. |
| 32 | +- **[MUST]** `verify=False` must not be used in any httpx transport. |
| 33 | +- **[MUST]** `base_url` must be validated as HTTPS. |
| 34 | +- **[MUST]** All direct dependency versions in `pyproject.toml` pinned exactly. |
| 35 | + |
| 36 | +### Data Classification |
| 37 | + |
| 38 | +- **CONFIDENTIAL:** `api_key`, impersonation tokens, credential object passwords, service account secrets |
| 39 | +- **INTERNAL:** `base_url`, user email addresses, workspace IDs, asset GUIDs |
| 40 | +- **PUBLIC:** SDK version, API endpoint names, asset type names |
| 41 | + |
| 42 | +### Review Checklist |
| 43 | + |
| 44 | +- [ ] `api_key` absent from all log output and exception messages; `Authorization` header stripped from error logs |
| 45 | +- [ ] Impersonation JWT token values absent from all log output |
| 46 | +- [ ] `verify=False` not present in any `httpx.HTTPTransport` or client config |
| 47 | +- [ ] `base_url` validated as HTTPS (not just HTTP-or-HTTPS via Pydantic `HttpUrl`) |
| 48 | +- [ ] Proxy URLs stripped of credentials before logging |
| 49 | +- [ ] `CredentialClient` response objects not logged with `password` field |
| 50 | +- [ ] All direct dependencies in `pyproject.toml` pinned exactly |
0 commit comments