# Security and operational boundaries

Passwords use scrypt, sessions are server-side, reset/verification tokens are hashed, and staff MFA is mandatory in production. Password, email and MFA changes require current credentials; email changes remain pending until single-use confirmation. Confirmation revokes existing sessions. MFA challenges are nonce-bound and consumed once. Capability guards run server-side; verifier/editor accounts cannot access client enquiry PII or billing administration.

Private evidence is authorized before download, random-key stored and screened for actual file length, supported magic bytes, extension and declared type. Production requires ClamAV INSTREAM scanning. Malware, an unavailable scanner, malformed replies or timeouts reject the upload. No insecure fallback accepts evidence. S3 buckets must remain private; object IAM and retention belong to the operator.

Outbound enquiry webhooks retain signed payloads, DNS/socket address verification and bounded retries; private/reserved IPv4, IPv6 and mapped addresses are rejected. Stripe verifies webhook signatures and stores processed event IDs. Billing and priority review never feed organic scoring.

Ranking drafts require preview, explicit approval, unchanged input hash, then atomic activation/recalculation. Previous versions remain available for rollback. Appeals require linked professionals and independent reviewers; decisions do not directly change scores. Credential and claim approval also reject self-review.

Audit payloads recursively redact secrets. Mail failures retain retryable metadata without logging raw tokens or SMTP credentials. New-browser and account security notices are delivered through configured mail/in-app channels. These controls reduce risk; they are not a guarantee of complete security.

Do not seed/reset production, commit `.env`, expose PostgreSQL/Redis/ClamAV, print configuration containing secrets, or delete production volumes. Use a TLS reverse proxy, explicit CORS origins, restricted trusted proxy hops, secure administrator devices, key rotation, monitored queues and tested encrypted backups. Review data retention and legal disclosures for the actual jurisdictions before launch.

A public-image CDN must be restricted to public image prefixes. Do not make the evidence bucket public or expose private prefixes through PUBLIC_FILES_URL. Leave that setting unset when serving authorized/public files through the API.

Protocol/deployment references: [ClamAV scanning manual](https://docs.clamav.net/manual/Usage/Scanning.html), [Docker Compose merge semantics](https://docs.docker.com/reference/compose-file/merge/). The production file is standalone so development service/port settings cannot silently merge into it.
