200 lines
10 KiB
Markdown
200 lines
10 KiB
Markdown
# Support and content-removal operations
|
|
|
|
Status: implemented intake and operator workflow. This document describes the
|
|
software behavior; it is not a legal opinion and does not establish that a
|
|
particular law applies to the operator.
|
|
|
|
## Separate queues
|
|
|
|
Who Need Help deliberately separates three mechanisms:
|
|
|
|
1. An authenticated in-product report targets exactly one request, assignment,
|
|
message, Activity, or Activity message and follows the existing audited
|
|
trust-and-safety workflow.
|
|
2. A support request covers account access, technical issues, safety concerns,
|
|
moderation appeals, privacy questions, data export, and account deletion.
|
|
3. A content-removal notice covers a precise item alleged to be illegal or to
|
|
infringe a right. TAKE IT DOWN notices have a dedicated public form and a
|
|
separate regime value in the removal queue.
|
|
|
|
The operator workspace is `/support/operations`. Support and legal access are
|
|
separate database-checked permissions that can be combined on one account;
|
|
administrators have both. Each queue supports search, status/type filtering,
|
|
assignee filtering, cursor pagination, and assignment only to an active member
|
|
of the corresponding team. Every creation and operator decision records an
|
|
audit event. The complete role matrix is documented in
|
|
`docs/staff-operations.md`.
|
|
|
|
## Public routes
|
|
|
|
- `/support` — ordinary support.
|
|
- `/account/delete` — external account-deletion request path suitable for use
|
|
as the Google Play account-deletion web resource.
|
|
- `/legal/content-removal` — general electronic notice-and-action intake.
|
|
- `/legal/take-it-down` — dedicated intimate-visual-material removal intake.
|
|
|
|
The request and Activity screens link to the general form with the exact local
|
|
content URL prefilled. Only same-origin relative paths can be prefilled this
|
|
way. The server validates one complete HTTP or HTTPS URL per line and accepts
|
|
at most 20 locations in one notice.
|
|
|
|
## Contact verification and status access
|
|
|
|
Public support submissions display a reference but never expose the signed
|
|
status token in the redirect. They are stored as `pending_verification`, are not
|
|
visible in the operator queue, and do not produce an operator alert. The private
|
|
status link is sent to the contact email. Opening it atomically verifies the
|
|
address, changes the request to `open`, makes it visible to authorised staff,
|
|
and enqueues at most one metadata-only operator alert when that optional mode is
|
|
enabled. Opening the same link again does not send another alert. An authenticated
|
|
submission uses the confirmed account email, is verified immediately, and enters
|
|
the queue without this extra step. Ongoing requester messages update the staff
|
|
workspace through PubSub and do not generate one operator email per message.
|
|
|
|
Exact repeats of the same unverified public support submission are represented
|
|
by one pending row. Its temporary fingerprint is a SHA-256 digest of normalized
|
|
form fields; it is cleared on verification and does not replace the original
|
|
record or its audit history. Existing unverified rows are quarantined rather
|
|
than deleted because no retention policy has been approved.
|
|
|
|
Email-link verification establishes access to the mailbox, not government
|
|
identity, authority to act for another person, or the truth of the claim.
|
|
Operators must perform any additional verification appropriate to the requested
|
|
action. In particular, an account-deletion request must not be fulfilled against
|
|
another person's account merely because an address was typed into the form.
|
|
|
|
Identity and contact fields may be omitted from a general report of sexual
|
|
material involving a minor. Such a report still receives an urgent queue state,
|
|
but no status email can be sent without a contact address.
|
|
|
|
## TAKE IT DOWN boundary
|
|
|
|
The dedicated form accepts exact URLs and textual identification only. It does
|
|
not accept file uploads and explicitly tells the submitter not to reproduce or
|
|
email the intimate image or video. A submitted notice is marked for urgent
|
|
review and records a review due time 48 hours after receipt.
|
|
|
|
The current product does not accept user-uploaded images or videos. The presence
|
|
of this preparedness workflow therefore does not claim that Who Need Help is a
|
|
covered platform, that a submitted item satisfies the statutory definition, or
|
|
that identical-copy detection exists. If media hosting is added, the operator
|
|
must review the then-current law, implement safe media hashing and
|
|
identical-copy handling where applicable, and test the entire removal path
|
|
before enabling uploads.
|
|
|
|
The primary US text currently requires a clear and conspicuous process and, for
|
|
a valid request to a covered platform, removal of the depiction plus reasonable
|
|
efforts concerning known identical copies as soon as possible and no later than
|
|
48 hours:
|
|
|
|
- <https://www.govinfo.gov/content/pkg/COMPS-18158/pdf/COMPS-18158.pdf>
|
|
|
|
## EU electronic notices
|
|
|
|
The general form captures the elements listed in Article 16 of Regulation (EU)
|
|
2022/2065: a reasoned explanation, exact electronic location, submitter name and
|
|
email subject to the child-sexual-abuse exception, and a good-faith accuracy
|
|
statement. It sends an acknowledgement when email is available and sends the
|
|
recorded decision after a verified-contact operator update.
|
|
|
|
- <https://eur-lex.europa.eu/eli/reg/2022/2065/oj/eng>
|
|
|
|
Product implementation alone does not determine the service's legal
|
|
classification, establishment, target markets, applicable national law, or
|
|
redress obligations. Those remain launch decisions requiring jurisdiction-
|
|
specific review.
|
|
|
|
## Email and operator notification
|
|
|
|
`EMAIL_FROM_ADDRESS` remains the outbound sender. Optional
|
|
`SUPPORT_INBOX_ADDRESS` has two separate effects:
|
|
|
|
- outgoing support/removal messages use it as `Reply-To`;
|
|
- it receives a metadata-only alert containing the reference, queue type, and
|
|
protected operator URL when an authenticated support case is created or a
|
|
public support contact is verified. Content-removal notification behavior is
|
|
kept separate because those notices can require prompt legal or safety review.
|
|
|
|
The alert intentionally excludes the free-text report and reported URLs. The
|
|
full record remains in the protected database queue. If the variable is empty,
|
|
intake and reporter acknowledgement still work, but no operator inbox alert is
|
|
sent. The configured inbox must be monitored operationally; the application
|
|
cannot prove staffing or response availability.
|
|
|
|
Anonymous submissions use two distinct private links. The confirmation link is
|
|
valid for `PUBLIC_CONTACT_VERIFICATION_MAX_AGE_SECONDS` (the initial pilot
|
|
policy is 24 hours). Confirming it moves the record into the permission-scoped
|
|
staff queue and sends a second status link. The status link lifetime is
|
|
`PUBLIC_CASE_ACCESS_MAX_AGE_SECONDS` (the initial pilot policy is one year).
|
|
Expired unconfirmed records are removed by the maintenance worker together with
|
|
their creation audit entry; confirmed support and legal records are outside this
|
|
cleanup. Each deployment can change both values through its own `.env` without
|
|
rebuilding the release.
|
|
|
|
## Account deletion and data export
|
|
|
|
The web application and Android WebView expose the account-deletion request from
|
|
account settings, and the public `/account/delete` route remains usable after an
|
|
app is uninstalled. The workflow verifies the contact and creates an audited
|
|
account-lifecycle request.
|
|
|
|
An authenticated user can download `/users/data-export`. The JSON export uses
|
|
explicit field allow-lists and includes data the account supplied or generated
|
|
through its own use of the product. It excludes password hashes, session and
|
|
OAuth tokens, push tokens and Web Push keys, and messages written by the other
|
|
participant. The response is an attachment with `Cache-Control: no-store`.
|
|
|
|
The restricted support workspace can run a read-only deletion preflight for a
|
|
verified, account-linked deletion case. It reports active help requests,
|
|
assignments, tracking sessions, activities/memberships, unresolved reports, and
|
|
open trust signals. It does not change those records or the support case.
|
|
|
|
Actual erasure/anonymization remains intentionally non-executable because the
|
|
operator has not selected a jurisdiction-specific retention policy for safety,
|
|
fraud, disputes, and legal records. An operator must not mark a request resolved
|
|
until the applicable approved data action has actually been completed and
|
|
communicated. Before enabling a destructive executor, legal review must define
|
|
which linked records are erased, anonymized, or retained and for how long; that
|
|
executor must then be tested against backups and relational constraints.
|
|
|
|
Google Play's current policy requires both an in-app path and an external web
|
|
resource when an app allows account creation:
|
|
|
|
- <https://support.google.com/googleplay/android-developer/answer/13327111?hl=en>
|
|
|
|
## Abuse controls and operational limits
|
|
|
|
`support_request`, `support_request_ip`, `content_removal_notice`, and
|
|
`content_removal_notice_ip` are supported names in the shared PostgreSQL rate
|
|
limiter. Public support and content-removal intake each check both their
|
|
normalized account/email scope and the trusted client-IP scope in one database
|
|
statement. This prevents a public submitter from evading the network policy by
|
|
rotating contact addresses. The initial pilot policy enables both scope types;
|
|
operators can replace the complete map through `RATE_LIMIT_POLICIES_JSON`, and
|
|
an explicit `{}` is reserved for isolated E2E/load runs. The values are product
|
|
policy, not a universal abuse or capacity threshold. CSRF protection,
|
|
validation, exact URL
|
|
limits, contact verification, staff authorization, and audit events apply
|
|
regardless.
|
|
|
|
The software does not provide emergency response. Threats to life or safety are
|
|
prioritized in the queue, while every public safety screen continues to direct
|
|
people in immediate danger to local emergency services.
|
|
|
|
## Reproducible browser verification
|
|
|
|
The isolated browser topology exercises these queues without using a public
|
|
deployment or real SMTP provider:
|
|
|
|
```bash
|
|
./scripts/e2e-run.sh tests/support-legal.spec.ts
|
|
```
|
|
|
|
The scenario registers a run-scoped requester, creates an isolated
|
|
administrator, submits authenticated support and both removal regimes,
|
|
verifies Mailpit messages, processes each permission-scoped queue, and checks
|
|
requester-visible status and decision delivery. The wrapper removes only its
|
|
unique Compose project, networks, database volume, and temporary image on
|
|
success, failure, or interrupt. This test does not establish staffing, legal
|
|
classification, or production email delivery.
|