DataTalksClub / DataTalksClub/website
/accounts/signup/ is open despite ACCOUNT_ALLOW_REGISTRATION = False
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Status
P0 owner decision required; no engineering is authorized yet. Keep the decision label until the product owner records one coherent account-creation posture below. The specifications do not currently select whether local signup is open, closed, or invite-only.
The declared and observed states conflict on current main (face8e4):
ACCOUNT_ALLOW_REGISTRATION = False, and identity inventory reports that value;- no
ACCOUNT_ADAPTERenforces the flag, so allauth's local email/password signup remains open; ACCOUNT_EMAIL_VERIFICATION = "none", so the issue's already-verified request probe creates an active, signed-in account for an unverified email;- social signup remains independently fail-closed and can only consolidate onto an existing durable account.
face8e4 is a documentation-presentation commit and did not add signup entrances. The newest entrances are a792553 (login-page “Create an account”, preserving next) and aff48ea (homepage hero “Join the community” now targets signup). They join the older masthead “Sign up free” and homepage closing “Create your free account” entrances.
Normative authority
_docs/specs/01-platform-architecture.md§ “Member signup, profile, Slack, and course registration”: email/password signup is conditional; verified ownership is required before profile completion, Slack eligibility, or course confirmation; return intent is server-side and path-only._docs/specs/07-security-privacy-operations.md§§ “Web and application security”, “Edge and application abuse controls”, and “Identity and authorization”: safe errors expose no object-existence clues; signup is in the 60 requests/source-IP/five-minute WAF class, initially count-only; application limits use normalized identity plus safe IP class; account linking requires verified ownership._docs/PROCESS.md: adecisionissue is not an engineering lane until the owner decides and PM re-grooms the selected contract.
Exact owner decision packet
The product owner must comment with one selection and answer every numbered item. A partial answer does not unblock engineering.
1. Account-creation posture
Choose exactly one:
- A — Closed: anonymous local email/password signup creates no account. Social providers remain login/linking paths for existing durable accounts only.
- B — Open: anonymous local email/password signup may create an account under the verification and pre-verification capability contract selected below. Social signup remains fail-closed unless the owner explicitly replaces that contract through Option C.
- C — Other: provide the complete invite-only, verified-link-first, provider-created, or other account-creation contract, including token lifecycle and safe denial behavior.
2. Email ownership and pre-verification capabilities
Record:
- whether ownership verification is mandatory, optional, or deliberately disabled;
- whether an unverified row is active, can receive a session, and which authenticated capabilities it may use;
- whether it may complete a profile, request Slack access, register/confirm a course, or reserve a durable normalized-email claim;
- resend/expiry behavior if verification exists.
A decision that permits immediate active unverified accounts must explicitly reconcile the verified-ownership requirements in specs 01 and 07, not merely accept the current accidental behavior.
3. Identity collision and squatting posture
Record the expected result when the submitted email, normalized email, or case-insensitive alias is already held, quarantined, inactive, or later presented by a verified social identity. The contract must say which identity survives and must not allow an unverified signup to capture or indefinitely deny a legitimate verified owner.
Social consolidation stays fail-closed on ambiguity. No option silently changes ConsolidatingSocialAccountAdapter.
4. Enumeration and abuse posture
Record:
- the user-visible response for existing, case-variant, quarantined, inactive, and fresh emails;
- the application-level normalized-identity plus safe-IP limit;
- whether the existing WAF signup rule remains count-only or has a separately reviewed promotion owner/date;
- whether honeypot coverage is included. CAPTCHA remains outside this issue unless separately reviewed with accessibility evidence.
Responses and observability must not disclose whether a durable account exists, and denied/replayed requests must create no user, EmailAddress, session, durable job, or misleading success event.
5. Public entrances and copy
Choose the destination/copy for every signed-out entrance as one coherent set:
- shared masthead “Sign up free”;
- homepage hero “Join the community” (
aff48ea); - homepage closing “Create your free account”;
- login-page “Create an account” links (
a792553), including safenextpreservation; - direct
/accounts/signup/GET and POST.
State whether a closed posture sends visitors to the existing /accounts/signup/ closed notice, to login, to Slack/community, or removes the account-creation claim. The copy must not promise account creation when the selected route cannot create one.
Safe interim behavior while the decision is open
- Do not selectively revert or hide only
a792553/aff48eaas a claimed security fix. Direct/accounts/signup/, the older masthead, and the older homepage closing CTA would remain, so selective link removal would neither close signup nor prevent scripted POSTs and would make navigation inconsistent. - Keep all five entrances in this issue's inventory and keep engineering blocked. Do not add further signup/account-creation entrances, campaigns, or copy while the posture is unresolved.
- Do not change the flag, adapter, verification mode, social adapter, or CTA destinations piecemeal.
- If the owner requires emergency containment before the full decision, they must explicitly authorize one coherent fail-closed interim contract: close both GET/POST mutation semantics, prove POST creates no identity/session/side effect, and make every entrance truthful in the same delivery lane. That authorization is itself an owner decision and must follow the issue lifecycle.
This is a policy-neutral freeze, not acceptance of the current open behavior.
Scope after the owner decides
- Make the setting (or documented replacement) agree with the adapter behavior allauth actually calls.
- Make identity inventory report enforced behavior, not a dead flag.
- Implement the selected ownership, collision, enumeration, denial, and abuse contract.
- Align every listed public entrance and direct route.
- Update the normative signup clause in spec 01 and any selected operational posture in spec 07.
- Add focused Django and browser coverage and complete independent tester/PM gates.
Non-goals
- No unrelated login, password reset, MFA, account deletion, profile-field, course-registration, or Slack redesign.
- No redesign of the existing open or closed signup pages.
- No implicit change to social consolidation/linking semantics.
- No CAPTCHA or broad WAF/Terraform rollout without its own reviewed scope and evidence.
- No migration or cleanup of existing ambiguous/unverified accounts unless the selected policy explicitly requires a separately bounded remediation lane.
Dependencies
- Blocking dependency: the complete product-owner response to items 1–5 above.
- After that response, PM must re-groom the selected option against a fresh clean
origin/mainbefore an engineer starts.
Acceptance criteria after selection
Nothing below may be checked until the owner decision is recorded and the selected option is re-groomed.
- The selected posture, verification/capability contract, collision survivor, enumeration response, abuse posture, and all entrance destinations/copy are recorded in this issue and in the normative specs.
- The effective setting and allauth adapter behavior agree; identity inventory reports the same observed value.
- Closed/denied POSTs create no user,
EmailAddress, authenticated session, durable job, or success event. - Fresh, exact-existing, case-variant, quarantined, inactive, and ambiguous identities follow the selected contract without object-existence disclosure or verified-owner takeover/indefinite denial.
- Social login/linking remains fail-closed on ambiguous ownership and cannot create or capture an account outside the selected contract.
- Safe internal
nextintent is preserved where applicable; external, credential-bearing, malformed, and auth-route loop targets are rejected without reflecting sensitive values. - Application abuse limits cover normalized identity plus safe IP class; WAF/honeypot disposition matches the recorded decision.
- Masthead, both homepage CTAs, login-page account links, and direct signup GET/POST are mutually consistent for signed-out visitors; signed-in navigation does not advertise signup.
- Focused Django tests cover both sides of the real gate (including an override proving it is not hard-coded), inventory parity, no-side-effect denials, collision/case variants, enumeration-safe output, and preserved safe intent.
- Independent Playwright verification covers the selected signup state and every changed entrance at desktop and mobile widths, including keyboard/focus/error-announcement behavior and screenshots read by the tester.
Browser scenarios
- A signed-out visitor follows each of the four visible entrances and reaches behavior/copy consistent with the recorded posture at desktop and mobile widths.
- Direct GET/POST to
/accounts/signup/produces the selected fresh, invalid, existing, case-variant, and denied outcomes without leaking account existence or creating forbidden side effects. - Safe internal
nextintent resumes only the authorized path; unsafe intent is discarded. - A signed-in visitor sees no contradictory signup invitation.
- An operator reads identity inventory and sees a registration value matching what the browser and POST path can actually do.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with _docs/specs/01-platform-architecture.md, _docs/specs/07-security-privacy-operations.md, and _docs/PROCESS.md, then review the owner decision packet and the listed signup entrances and direct route. Engineering is blocked until items 1–5 are decided and PM re-grooms the work; done means the selected contract, effective behavior, specs, focused Django coverage, and Playwright verification all agree.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, playwright, python
- Domain
- authentication, backend, documentation, security, testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100