# Security

How Pozy protects sign-in, API keys, webhooks and team access, and the logs you can use to see who did what.

This page describes the controls you get in Pozy today: how people sign in, how API keys and webhook secrets are handled, how access inside a workspace is limited, and what is logged. For where data is stored, see [Data residency](https://pozy.ai/docs/security/data-residency).

## Signing in to the dashboard

| Method | Notes |
| --- | --- |
| Email and password | Passwords need at least 8 characters. You confirm your email address from the link Pozy sends before you can sign in. Password reset links work for one hour. |
| Google | Sign in with a Google account. |
| Single sign-on | SAML 2.0 or OIDC through your identity provider, verified by DNS. Available on every workspace. See [SSO](https://pozy.ai/docs/security/sso). |
| Two-step verification | A TOTP authenticator app plus backup codes, on top of password sign-in. See [Two-step verification](https://pozy.ai/docs/security/two-factor). |

Sessions last 30 days and are extended while you use the dashboard. **Settings → Security** lists every signed-in device, with a sign-out button per device and **Sign out everywhere**. Signing out does not affect API keys.

## API keys

- A key looks like `pz_live_` followed by 64 hex characters. It is shown once, when you create it. Pozy stores only a SHA-256 hash and a short preview, so a lost key cannot be recovered: create a new one and revoke the old one.
- Revoking a key takes effect on the next request.
- Narrow every key to what it needs. A key can be limited to some profiles (`scope: "profiles"`), made read-only (`permission: "read"`), barred from resource groups such as `billing` or `webhooks` (`disabledResourceGroups`), and set to expire (`expiresIn`, in days).
- Only owners, admins and full-scope read-write keys can create or revoke keys. Key creation and revocation are written to the activity log.

See [Authentication](https://pozy.ai/docs/getting-started/authentication) for the fields and errors, and [Keys for your customers](https://pozy.ai/docs/build/tenant-keys) for per-tenant keys.

> **Keep keys on your server:**
> 
> The API accepts requests from any origin, so a key in browser or mobile code can be copied and used by anyone who opens your app. Call Pozy from your backend, and give AI assistants the [MCP server](https://pozy.ai/docs/mcp) with OAuth instead of a raw key.

## Webhooks

- Every delivery is signed. `X-Pozy-Signature` is the hex HMAC-SHA256 of the raw request body, keyed with the endpoint's secret (`whsec_...`). Verify it before you trust a payload. See [Verify signatures](https://pozy.ai/docs/webhooks/signatures).
- Signing secrets are encrypted at rest with AES-256-GCM.
- Pozy does not follow redirects when it delivers, so a delivery cannot be bounced to another host.
- Webhook endpoints are managed by owners and admins, or by keys that have not disabled the `webhooks` group.

## Access inside a workspace

Every member has one of five [roles](https://pozy.ai/docs/security/roles): owner, admin, member, viewer or billing. The role is checked on every API call made with a dashboard session or an OAuth token, so a viewer's write request is refused by the server, not hidden in the UI.

API keys do not have a role. They are limited by their own settings instead: a key restricted to some profiles gets `403 profile_out_of_scope` for anything outside them, a read-only key gets `403 read_only_key` on writes, and a disabled resource group returns `403 resource_group_disabled`.

## Apps you have signed in to

When you connect an AI assistant to the [MCP server](https://pozy.ai/docs/mcp), Pozy issues an OAuth token for that app. List the apps that hold tokens for your user with [`GET /v1/me/connected-apps`](https://pozy.ai/docs/api/listConnectedApps), and revoke one with [`DELETE /v1/me/connected-apps/{clientId}`](https://pozy.ai/docs/api/revokeConnectedApp). The same list is under **Settings → Connected apps**.

## Logs

`GET /v1/logs` and **Logs** in the dashboard show up to 90 days of history.

| `type` | What it contains | Who can read it |
| --- | --- | --- |
| `api_request` | Every API call: method, path, status, duration, the key that made it and its request id. | Owners, admins and members |
| `webhooks` | Every webhook delivery attempt and the endpoint's response. | Owners, admins and members |
| `activity` | Team and security changes: invites created, accepted, declined and revoked; members removed, role changes, members leaving; workspace changes; SSO connected, removed and domains verified; API keys created and revoked. Each entry names who did it and, for dashboard actions, the IP address. | Owners and admins |
| `publishing`, `connections`, `messaging`, `workflow_event` | What happened to posts, account connects, messages and automations. | Owners, admins and members |

Filter by `requestId` to find one call: every response carries `X-Request-Id`, and you can send your own `x-request-id` header to correlate with your logs.

```bash
curl "https://api.pozy.ai/v1/logs?type=activity&days=30" \
  -H "Authorization: Bearer $POZY_API_KEY"
```

## Report a security issue

Email support@pozy.ai with "Security" in the subject. Include the request ids involved, never a full API key or secret. The same contact is published in [`/.well-known/security.txt`](https://pozy.ai/.well-known/security.txt).

## In this section

- [Single sign-on](https://pozy.ai/docs/security/sso): SAML and OIDC with DNS-verified domains.
- [SCIM provisioning](https://pozy.ai/docs/security/scim): Not available yet, and how to handle joiners and leavers today.
- [Two-step verification](https://pozy.ai/docs/security/two-factor): TOTP and backup codes.
- [Roles](https://pozy.ai/docs/security/roles): What owners, admins, members, viewers and billing users can do.
- [Data residency](https://pozy.ai/docs/security/data-residency): Where data is stored and how long it is kept.

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`GET /v1/auth/verify`](https://pozy.ai/docs/api/verifyCredential) | Verify credential |
| [`GET /v1/api-keys`](https://pozy.ai/docs/api/listApiKeys) | List keys |
| [`POST /v1/api-keys`](https://pozy.ai/docs/api/createApiKey) | Create key |
| [`DELETE /v1/api-keys/{keyId}`](https://pozy.ai/docs/api/deleteApiKey) | Delete key |
| [`GET /v1/me/connected-apps`](https://pozy.ai/docs/api/listConnectedApps) | List connected apps |
| [`DELETE /v1/me/connected-apps/{clientId}`](https://pozy.ai/docs/api/revokeConnectedApp) | Revoke connected app |
| [`GET /v1/logs`](https://pozy.ai/docs/api/listLogs) | List activity logs |
