10 KiB
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:
- An authenticated in-product report targets exactly one request, assignment, message, Activity, or Activity message and follows the existing audited trust-and-safety workflow.
- A support request covers account access, technical issues, safety concerns, moderation appeals, privacy questions, data export, and account deletion.
- 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 sends one metadata-only operator alert. 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.
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:
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.
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:
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:
./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.