# Public Access Contract

> **Documentation contract only.** No access-policy engine implementation.  
> Architecture: [published-resource-architecture.md](../architecture/published-resource-architecture.md) · [ADR-022](../architecture/adr/ADR-022.md)  
> Contract version: `public-access.v1` (additive; open strategy registry)

---

## 1. Purpose

A **Public Access Policy** describes how a Published Resource may be reached. Strategies are composable and extensible. Experience stores **policy metadata refs** for presentation/publishing; it **never owns authentication**.

| Concern | Owner |
| --- | --- |
| Authentication / SSO / session | Identity / Core ([ADR-004](../architecture/adr/ADR-004.md), [ADR-005](../architecture/adr/ADR-005.md)) |
| Payment / paid unlock | Payment ([ADR-020](../architecture/adr/ADR-020.md)) |
| Membership / tier gates | Loyalty ([ADR-011](../architecture/adr/ADR-011.md)) |
| OTP / messaging challenges | Communication ([ADR-012](../architecture/adr/ADR-012.md)) |
| Publish presentation + access policy metadata | Experience |

---

## 2. Access strategies (open registry)

Illustrative keys — **not closed**:

| Strategy key | Meaning | Auth owner |
| --- | --- | --- |
| `public` | Anyone with the URL | — |
| `private` | Not publicly listed; direct knowledge may still apply | — |
| `authenticated` | Any signed-in user | Identity |
| `tenant_members` | Members of the tenant | Core / Identity |
| `role_based` | Specific roles/permissions | Identity / Core entitlement |
| `password_protected` | Shared password challenge | Identity / Experience metadata + Identity verify |
| `otp_protected` | OTP challenge | Communication + Identity |
| `paid_access` | Unlock after payment | Payment (`publish_id`) |
| `invitation_only` | Invite token / list | Identity / Core |
| `signed_url` | Cryptographic signed link | Platform edge / Identity |
| `temporary_link` | Time-bound link | Short Link / Identity |
| `expiration` | Absolute/relative expiry on access | Policy metadata |
| `rate_limited` | Request rate caps | Edge / platform |
| `geo_restricted` | Reserved | Future |
| *future.*\* | Any registered strategy | Declared owning service |

---

## 3. Policy record (conceptual)

```
PublicAccessPolicy {
  publish_id
  tenant_id
  strategies[]          # ordered / composed
  strategy_config_refs  # opaque refs to owning services
  expires_at?
  rate_limit_ref?
}
```

Consumers evaluate access by consulting the **owning service for each strategy**, keyed by `publish_id`. Experience does not become an IdP.

---

## 4. Rules

1. Experience **MUST NOT** own authentication, password hashing as IdP, OTP providers, payment capture, or loyalty membership ledgers.
2. `paid_access` always references Payment via `publish_id`.
3. `otp_protected` always routes challenges through Communication.
4. Additive: resources with no policy default conceptually to `public` when `publish_status=published` and `visibility=public` (implementation deferred).
5. Geo restriction is **reserved** — document only.

---

## 5. Related

- [Published Action Registry](published-action-registry.md)
- [Embed Contract](embed-contract.md)
- [Published Resource Contracts](published-resource-contracts.md)
