# pp_endpoints

One CSV per Python microservice that calls PP. Each row is one `(endpoint × resource_type × action)` gating decision found in production code.

All files use the same six columns: `microservice, endpoint, resource_type, action, pp_authorization_method, source_file`.

## Coverage

| Service               | Rows    | Framework | Pattern                                   | Notes                                                                                                                                                                                                                       |
|-----------------------|---------|-----------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ows-dmp`             | 140     | FastAPI   | Pre-SDK `Permission()` (fansifter-common) | Heaviest PP user. `Permission(resource, action)` class attrs + `auth_service.authorize_account` / `get_account_access_for_permission`. Endpoints resolved via `Annotated[<X>, Inject()]` / `Provide[<X>]` route extraction. |
| `ows-email-campaigns` | 42      | FastAPI   | Pre-SDK `Permission()`                    | Same shape as ows-dmp. Includes verbs beyond CRUD: `email_campaign,schedule`, `email_campaign,send`.                                                                                                                        |
| `ows-product-review`  | 33      | Flask     | python-pdp-sdk                            | All on `review_queue` resource; mostly `view` / `review` actions.                                                                                                                                                           |
| `ows-account`         | 10      | Flask     | python-pdp-sdk                            | All on `/v2/` paths. Uses colon-namespaced field-scoped actions: `update:country_id`, `update:service_tier`, `update:internal_staff`.                                                                                       |
| `ows-abacus-account`  | 5       | Flask     | python-pdp-sdk                            | All `is_authorized_many`, all on `account` / `view_abacus_account_info`.                                                                                                                                                    |
| `ows-product-staging` | 34      | FastAPI   | python-pdp-sdk                            | Every endpoint using the `assert_authorization` wrapper (and 2 endpoints calling `is_authorized_for_tenant` at `auth.py:280` directly: `POST /bulk-session`, `GET /bulk-template`). All on `digital_audio.bulk_create`. Endpoints gated by `assert_access` use the legacy non-PP path and are excluded.                                                  |
| `ows-abacus-state`    | 3       | Flask     | python-pdp-sdk                            | Includes the only `is_authorized_many_resources_and_actions` call in the dataset.                                                                                                                                           |
| `ows-abacus-schedule` | 3       | Flask     | python-pdp-sdk                            | New resource type: `abacus_schedule`.                                                                                                                                                                                       |
| `ows-users`           | 2       | Flask     | python-pdp-sdk                            | `identity` / `list_employees`.                                                                                                                                                                                              |
| `ows-royalties`       | 1       | Flask     | python-pdp-sdk                            | `accounting_period` / `view`.                                                                                                                                                                                               |
| `ows-permissions`     | 1       | Flask     | python-pdp-sdk                            | `identity` / `manage_employee` (PP service's own admin endpoint).                                                                                                                                                           |
| **Total**             | **274** |           |                                           |                                                                                                                                                                                                                             |

## Patterns observed

- **python-pdp-sdk** (newer): handlers call `pdp_authorization_backend.is_authorized(...)` / `is_authorized_many(...)` / `get_authorized_tenants(...)` / `is_authorized_many_resources_and_actions(...)` directly.
- **fansifter-common `Permission()`** (older, pre-SDK): handlers declare `Permission(resource, action)` as class attributes and pass them through `auth_service.authorize_account(permission=...)` and similar helpers. Used by `ows-dmp` and `ows-email-campaigns` only — **don't replicate this pattern in new services**.

## Column reference

All CSVs in this dir share the same six columns:

| Column                    | Meaning                                                                                                                                                                                      |
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `microservice`            | Service repo slug (e.g. `ows-account`). Same value for every row in a file.                                                                                                                  |
| `endpoint`                | `<METHOD> <full_path>` of the route handler (e.g. `POST /v2/vendors`). For fansifter-team services, the path is the FastAPI router prefix concatenated with the route path.                  |
| `resource_type`           | The cerbos resource type checked (e.g. `account`, `audience`). Cross-reference against `pp_cerbos/cerbos_resource_actions.csv`.                                                              |
| `action`                  | The cerbos action checked (e.g. `view`, `create`, `view:basic`, `update:country_id`).                                                                                                        |
| `pp_authorization_method` | Which PDP method gates the endpoint: `is_authorized`, `is_authorized_many`, `is_authorized_many_resources_and_actions`, or `get_authorized_tenants`. See SKILL.md for the full descriptions. |
| `source_file`             | `<repo-relative path>:<line>` of the call site that performs the PP check (the handler file for fansifter `Permission()` declarations, the call site for direct SDK calls).                  |

## Services with the SDK installed but no live PP calls (excluded from this dir)

`ows-payee`, `ows-payment`, `ows-ledger`, `ows-store`, `ows-product`, `ows-product-digital`, `ows-track`, `ows-contributor`, `ows-project-manager`. They have `python-pdp-sdk` in deps but no `is_authorized*` call sites yet.
