# Public registration, ingress identity and launch evidence This release adds explicit ingress contracts and an offline prerequisite review. It does not change an existing Space's visibility, register users, send test mail, or certify a concurrent-user capacity. Keep the existing session, encryption and storage keys when upgrading. Test the complete public path on a separate staging deployment before opening the production application. ## Authentication and administrative authority Local registration creates an ordinary, unverified account. Email verification is required before login. Owning an organization does not grant platform authority. The accounting page, its JavaScript and its administrative API require a current platform administrator session. CSRF and origin checks still apply to mutations. Never bootstrap every new user as an administrator to make registration work. Configure production mode, the exact HTTPS public origin, a preserved strong session secret, a production PostgreSQL deployment and working account email. For HF retain a verified encrypted SMTP endpoint on an allowed outbound port, such as SMTP2GO port 443 with `PF_SAAS_SMTP_SSL=true` and `PF_SAAS_SMTP_STARTTLS=false`, or optionally use `PF_SAAS_MAIL_MODE=resend` with its server-side API key and verified sender. The HF checker accepts SMTP on ports 80, 443 or 8080 only with exactly one TLS mode; an allowed port alone does not prove that the provider offers SMTP there. Linux/Docker can also use encrypted SMTP on its permitted ports. Consult the account mail deployment guide for durable delivery, retries and operator failure inspection. A successful registration HTTP response alone does not establish delivery of its verification message. Test verification, password reset and invitation separately. Set positive account-wide concurrent-job, queued-job, monthly-compute, storage and owned-organization limits as well as organization and deployment limits. These apply independently: creating another organization must not multiply an account's allowance. Authenticated rate admission is also account-wide. ## Configure the actual proxy contract `PF_SAAS_TRUSTED_PROXY_CIDRS` is empty by default. Only an actual socket peer in these explicitly configured networks can supply a forwarded client address. Do not populate it with guessed HF ranges, all private address space, or a default route. If the provider cannot establish a trustworthy forwarding contract, the public ingress remains unqualified. Resolve that with the ingress operator or use an ingress whose identity and forwarding behavior you control. Keep Uvicorn proxy rewriting disabled (`proxy_headers=False` or `--no-proxy-headers`). Otherwise the boundary may receive an already rewritten peer and cannot verify the transport source. PF never trusts forwarded host or protocol headers to establish the application origin. | Setting | Contract | |---|---| | `PF_SAAS_PROXY_HEADER_MODE=none` | Use the socket client identity; forwarded headers cannot select it. Use only when this is actually the end-client connection, or after PF's authenticated gateway boundary. Leave proxy CIDRs empty. | | `PF_SAAS_PROXY_HEADER_MODE=append` | Compatibility default. One trusted immediate proxy appends its observed client IP to X-Forwarded-For. PF uses the last address. The proxy must disable client-port suffixes. | | `PF_SAAS_PROXY_HEADER_MODE=single` | The trusted immediate proxy replaces X-Forwarded-For with exactly one observed client IP. Multiple values fail. | | `PF_SAAS_PROXY_HEADER_MODE=chain` | All trusted proxy hops are listed explicitly. PF walks from the right and selects the first untrusted address. A chain containing only trusted proxies fails. | | `PF_SAAS_PROXY_REQUIRE_HEADER=true` | Require the chosen forwarding header from trusted peers. Missing headers fail except GET health/readiness probes. Compatibility default is false; the public review requires true when forwarding is enabled. | Restrict backend network ingress to the intended proxy. The proxy must remove or correctly append incoming forwarding headers according to the chosen contract. Never accept a user-supplied client-IP header as a workaround for shared HF proxy addresses. A single shared IP would cause unrelated users to share the public authentication rate window; trusting arbitrary XFF would instead allow its bypass. The optional HF gateway for an external Linux/Docker backend has equivalent `PF_HF_TRUSTED_PROXY_CIDRS`, `PF_HF_PROXY_HEADER_MODE` and `PF_HF_PROXY_REQUIRE_HEADER` settings. Its compatibility default is `chain`. Configure and test these in the gateway process, not only in the backend. The gateway strips incoming forwarding and PF gateway headers, then sends an authenticated client identity to the backend. Its independent gateway secret must stay server-side. The backend's `HFGatewayBoundary` verifies that secret and the canonical origin before using the supplied identity. Keep ordinary backend proxy CIDRs empty and mode `none` for this path. A backend check cannot prove that the public HF gateway has been configured correctly: retain both configuration records with the ingress test evidence. When the backend enables `PF_SAAS_HF_GATEWAY_SECRET`, the offline review also requires `--gateway-policy gateway-policy.json`. Export the following non-secret values from the actual gateway configuration (these addresses are examples): ```json { "public_url": "https://pf.example.org", "upstream_url": "https://backend.example.org", "trusted_proxy_cidrs": "REPLACE_WITH_VERIFIED_PROXY_NETWORKS", "proxy_header_mode": "single", "proxy_require_header": true } ``` Never include the gateway secret in this file. The policy must match the public origin and binds the fixed upstream and forwarding settings into the evidence fingerprint. This remains an operator-exported policy, not a remote settings fetch. Use two independent external clients to confirm distinct client identities. Send forged XFF prefixes and duplicate/malformed forwarding headers and verify they cannot choose a different identity or evade authentication admission. Test direct origin access without passing the intended ingress. Retain sanitized results and the precise ingress configuration; do not publish client IPs or credentials in public logs or expose a public diagnostic endpoint to reveal them. ## Shared limits and overload behavior Authentication limits use database time and one locked counter per action and hashed identity. Independent API processes share the same counter. Distributed and managed HF authenticated-account rate windows are also database-backed. Native HF remains one fenced controller; its authenticated read-rate window is bounded in process and resets on restart, which avoids per-read WAL writes. That controller is not an independently replicated API tier. Per-process HTTP and upload admission remains bounded. Saturation returns a retryable response; database pool exhaustion and operational connection failures return sanitized 503 responses with `Retry-After`. Authentication/account rate rejection returns 429. Client retries should honor these bounds and use backoff; they must not create duplicate mutations. Deploy upstream connection/body/rate controls as well: application counters cannot absorb an unbounded network flood. ## Offline review and evidence Run from the release root with the exact deployment's `PF_SAAS_*` environment available locally. The tool reads configuration without creating a session secret or data directory. It neither connects to providers nor changes remote resources. It does not print secrets. ```text python release_tools/check_public_readiness.py --target-users 200000 ``` The first report is expected to fail missing live evidence. It prints the `configuration_sha256` that binds subsequent evidence to non-secret policy settings, security source bytes, database target and optional gateway policy. The mail fingerprint binds the effective sender and SMTP host, port and TLS settings. Changing those settings invalidates prior evidence and requires fresh delivery checks. Credentials are excluded. Record a UTC Unix timestamp and retained test-record references. The schema below deliberately contains false values; replace each only after that specific check succeeds against the target staging deployment. Never turn these into unconditional true defaults in deployment automation. ```json { "schema": 1, "configuration_sha256": "COPY_THE_REVIEWED_CONFIGURATION_SHA256", "checked_at_unix": 0, "ingress": { "record": "retained-ingress-test-record", "distinct_client_addresses": false, "forged_forwarding_cannot_select_identity": false, "direct_origin_cannot_bypass_ingress": false, "raw_asgi_socket_peer_preserved": false }, "authorization": { "record": "retained-authorization-test-record", "anonymous_admin_denied": false, "tenant_admin_denied": false, "cross_tenant_private_objects_denied": false, "registration_creates_non_admin": false }, "mail": { "record": "retained-mail-test-record", "verification_delivered_and_consumed": false, "password_reset_delivered_and_consumed": false, "invitation_delivered_and_consumed": false, "used_token_rejected": false }, "operations": { "record": "retained-recovery-and-operations-record", "backup_restore_verified": false, "stopped_execution_recovery_verified": false, "overload_is_bounded": false, "secret_rotation_and_rollback_documented": false } } ``` For Cognito replace the `mail` group with an `identity_provider` group containing a `record` and these three booleans: `verified_subject_required`, `existing_account_binding_explicit`, `logout_and_session_expiry_verified`. Identity-provider signup/recovery email must also work; changing auth modes is not an implicit migration of existing accounts. ```text python release_tools/check_public_readiness.py --target-users 200000 --evidence public-launch-evidence.json ``` Exit 0 means the listed configuration prerequisites and operator attestations are complete; exit 1 means some are missing; exit 2 means the input is invalid. Evidence older than 30 days, future-dated evidence and changed policy fingerprints fail. The report explicitly identifies these records as operator attestations, not independent verification. Preserve the exact release checksum and both gateway/backend settings with the records. Re-run affected checks after code, ingress, authentication, provider, data-residency or deployment topology changes. Normal production startup still performs its full settings validation. `public_configuration_ready` is a prerequisite check. `public_launch_prerequisites_attested` adds the operator records. `capacity_qualified` and `deployment_authorized` are always false here. Run the separate mixed-workload qualification at the intended active concurrency with actual provisioned databases, workers, providers, storage and ingress. Native single-controller HF cannot be certified for hundreds of thousands simply by raising its environment limits. Distributed Docker and managed HF need measured fleet capacity; managed HF uses external PostgreSQL. The software release does not itself provision that fleet or open production access. ## HF application and source visibility HF documents **protected** Spaces as public applications with private repository source, available on the applicable paid plans. Ordinary public visibility also publishes the repository. Keep the scientific code-only Space and data buckets private. Opening an application does not grant platform administration inside PF. The native and managed full-release updaters accept a controller that the authenticated Hub metadata explicitly identifies as `visibility="protected"`, or a private controller. They do not change visibility. `private=False` without explicit protected metadata is refused: it does not distinguish protected from public. Conflicting or unknown visibility is also refused. If an older API/client omits protected metadata, stop and resolve metadata support; never remove the source-privacy check or relabel unknown data as protected. Code-only archive uploads continue to require a private repository. Reference documentation, checked 2026-10-09: - [HF Space visibility](https://huggingface.co/docs/hub/spaces-overview#space-visibility) - [HF repository visibility API](https://huggingface.co/docs/huggingface_hub/en/package_reference/hf_api#huggingface_hub.HfApi.update_repo_settings) Local regression tests cover transport spoofing, separate client counters across independent service instances, malformed forwarding rejection, protected-source metadata guards, and anonymous/ordinary-user denial on accounting administration. They exercise isolated fixtures, not public HF ingress or live capacity.