How to add age verification at signup without storing ID scans
Forty attorneys general just told a bankruptcy court that a self-reported birthdate isn't age verification. The options you have at signup, what each one keeps, and where each one fails an audit.
Age assurance is the process of establishing whether a user meets an age threshold (such as 13, 16 or 18) with more evidence than a self-reported birthdate. At signup, the main options are platform attestation from Apple or Google, age estimation with a step-up for borderline results, reusable age credentials, and photo ID matching as a last resort. Whichever you use, store the result, the method and the time, not the document.
On October 14, 2026, New York Attorney General Letitia James and a bipartisan coalition of 39 other attorneys general told a bankruptcy court that Character.AI shouldn't be sold without strong protections for the people whose conversations it holds. The filing is in the bankruptcy of Character Technologies, Inc. Among the conditions the coalition wants attached to any sale is "effective age verification based on more than self-disclosure."
That's one filing in one bankruptcy, and it binds nobody else. But forty state law enforcement offices just told a court that a self-reported birthdate doesn't count as verification, and asked for the fix in the terms of a sale. The practical consequence for everyone else: age is becoming an attribute on the user record, with a method and a timestamp, instead of a checkbox on a signup form.
What does the attorneys general's filing ask for?
The coalition's asks are conditions on a sale, not a technical standard. Age verification beyond self-disclosure is one item. The others include a comprehensive privacy program, clear disclosures about data use, limits on using private conversations for AI training without valid consent, and a chance for users to access and delete their information before any sale.
The investigation behind it found weak age checks, misleading safety claims, chatbots posing as licensed professionals, and potential violations of state privacy laws. The scale matters: the platform has more than 20 million monthly users, and about two million accounts registered to users who self-declared as under 18.
New York has also legislated here already. AI companion companies must take reasonable steps to detect and respond to expressions of suicidal thoughts or self-harm, and must remind users at the start of each conversation and at least every three hours that they're talking to an AI. Treat the filing as a signal and the statute as what you comply with. The rest depends on your jurisdiction, and none of this is legal advice.
Why is this an identity problem, not a moderation problem?
One sentence in the coalition's announcement explains it. Character.AI voluntarily restricted open-ended chats for users it identified as under 18, but the coalition says those restrictions are "easily circumvented and fail to protect minors the company does not identify."
Safety controls only apply to the users you can classify. The objection isn't that the restrictions were missing; it's that the classification underneath them was weak, and easy to route around. In one test, an account registered to a 14-year-old reached sexual role-play by switching from text to voice mode.
In some places the stakes already have numbers. Under the UK Online Safety Act, failing to comply can mean fines of up to 10% of qualifying worldwide revenue or £18 million, whichever is greater. And on June 15, 2026, the UK government announced a ban on social media for under-16s, with age assurance at its center, alongside a minimum age of 18 for AI chatbots that simulate romantic or sexual relationships.
Why shouldn't you store ID scans?
The reflex fix is to ask for a government ID at signup. That turns a classification problem into a data-custody problem, and the custody problem is worse.
In October 2025, Discord disclosed that about 70,000 users may have had government ID photos exposed. These were images collected for reviewing age-related appeals, and the breach was at a third-party customer service provider, not Discord's own systems. Discord later named the provider as 5CA, which said none of its systems were involved. The attackers tried to extort a ransom.
Note where the documents were: in an appeals process, with a vendor, long after the signup flow that collected them. That's how ID scans pile up: not in the system you designed, but in the support tooling attached to it.
The Character.AI filing adds a second argument. The company holds private chats and voice calls, mental health disclosures, ages and identifying device data, and the AGs warn that data could pass to a new owner through the bankruptcy. Whatever you keep is an asset in an insolvency. A folder of customers' passports is an asset you'd rather not have on the list.
UK regulators are explicit that you can't trade privacy for safety here. Ofcom's guidance says providers must comply with data protection law when doing age assurance, and that every method processes personal data, so privacy has to be designed in from the start. What providers covered by Part 5 of the Act must keep is a written record of the kinds of age assurance they use, how they use them, and how they considered privacy and data protection when choosing. The record is of the method, not the document.

Option 1: Platform attestation from Apple or Google
Apple and Google now hand you an age signal from the layer below your app.
Apple's Declared Age Range API asks the person to share an age range with your app. Alongside the range, it can tell you how that range was established. iOS 26 introduced selfDeclared and guardianDeclared; iOS 26.2 added method-of-confirmation values: governmentIDChecked, paymentChecked and checkedByOtherMethod, each with a guardian variant. iOS 26.4 added requiredRegulatoryFeatures. From iOS 26.2 you can test it in the sandbox, including approval changes and consent revocation. Revocation is a server event, not a client state: when a parent revokes consent, Apple prevents the app from launching, and you receive a RESCIND_CONSENT App Store Server Notification.
Google's Play Age Signals API (beta) started returning signals for users in Brazil on March 17, 2026, under the Digital ECA, and for eligible Texas users who created accounts after May 28, 2026, under Texas SB 2420, the App Store Accountability Act. That law has been in court: a federal judge blocked it in December 2025, and on May 28, 2026 the Fifth Circuit issued an administrative stay that let it take effect while the appeal continues.
What it keeps. An age band and, on Apple, a label saying how it was established. You never handle a document, and Google says its client library collects no data.
Where it fails an audit. The platform doesn't take the obligation off you. Apple says developers are responsible for their own age restrictions, and Ofcom says the regulated service is responsible for the process being highly effective, including when it relies on a check done elsewhere. Then there's the signal itself, which can come back selfDeclared, and Ofcom lists self-declaration as not capable of being highly effective. Store the band and drop the declaration, and you've thrown away the only field that tells you whether you have a check or a guess. Coverage is the last gap: sharing is the user's choice, Google limits use to apps updated by Google Play, and none of it exists on your web signup.
User experience cost. A system sheet. It's the cheapest option, which is why it's tempting to rely on it alone.
Option 2: Age estimation, with a step-up when unsure
Ofcom's list of methods that can be highly effective includes facial age estimation, email-based age estimation, open banking, mobile network operator checks, credit card checks, digital identity services and photo ID matching. The estimation methods are the ones you can run without asking for a document: estimating age from a selfie, or from the other online services where an email address has been used.
Estimation returns a probability, not an answer, and the error rates are public. In NIST's May 2024 evaluation of six age estimation algorithms, there was no single standout; on the visa photos shared with its 2014 round, mean absolute error improved from 4.3 years to 3.1. Error rates were almost always higher for female faces than male ones, for reasons NIST says are unknown, and accuracy varied with image quality, sex, region of birth and age. Even for one person, the estimate moves: changing expression, or putting on or taking off glasses, shifted every algorithm's output, and frames from one phone video varied by a few years.
An average error of about three years is the same size as the gap you're trying to resolve around an 18 threshold. Ofcom's answer is the challenge age: set the bar above the legal threshold and send everyone estimated below it to a stronger method. Ofcom's July 2026 report on age assurance also tells services using facial estimation to add liveness detection, to consider repeating checks, to use proportionate anti-circumvention measures, to offer a variety of methods, and to give users an appeals process.
What it keeps. A selfie or an email address, a score and a decision. The image should be discarded; the score and the decision are what you keep.
Where it fails an audit. Estimation with no challenge age and no step-up fails on accuracy. No demographic evidence from your vendor fails on fairness, and NIST's results tell you which direction the bias tends to run. No appeals process leaves adults wrongly classified as children with nowhere to go.
User experience cost. The step-up, and it lands on real adults who get estimated too young. Budget for the appeals process and staff it, and remember that appeals are where Discord's ID images were held.
Option 3: Reusable age credentials
The third option moves the check off your stack. Digital identity wallets let a user verify an attribute such as age once, then share just that attribute (that they're an adult) with the services that ask.
The EU is building a reference version. On July 14, 2025, the European Commission released the first version of an age verification blueprint, a "mini-wallet" built on the same technical design as the upcoming European Digital Identity Wallets. Services receive only confirmation that the user is over 18, and no other personal details. The technical specification makes zero-knowledge proofs the preferred way to present that proof, with a plain mDoc presentation as fallback, and asks issuers to check that the requesting app is a genuine, untampered instance before issuing. The Commission ties it to Article 28(1) of the Digital Services Act, which "requires online platforms accessible to minors to ensure a high level of safety, security and privacy." Denmark, France, Greece, Italy and Spain were the first to adopt it, for their national wallets or apps.
Open banking has the same shape with a bank as the issuer: you get confirmation of whether the user is over 18, not their date of birth.
What it keeps. A yes or no against a threshold, plus the issuer and the time. That's the minimum record, and it's the one you want.
Where it fails an audit. Coverage and verification, and they're linked. A credential works for users who have the wallet, in the countries where it has launched; for everyone else it's a dead end unless you ship a second path. And when you rely on a check done elsewhere, both the original check and the way it reaches you have to be highly effective. A token you accept without verifying where it came from is self-declaration with extra network calls.
Where does photo ID fit?
Photo ID matching is on Ofcom's list of methods that can be highly effective, and the method is reasonable: read the data from an uploaded document and compare it to an image of the user taken at the time. The liability isn't in checking an ID. It's in keeping one.
So make it the last branch, after attestation, estimation and credentials have failed, and treat the output as a verdict, not a file. Keep the result, the method, the time and the vendor's transaction reference. Don't keep the scan, and make sure your support tools can't quietly become the place one lives.
Credit card checks deserve the same scrutiny. Ofcom accepts them as a method while noting that having credit card details isn't evidence that the user is the cardholder.
How should you compare the options?
How should you model the result?
Every option produces the same three things: the threshold you asked about, an answer, and where the answer came from. Store all three. A boolean is_adult column can't be audited, because you can't reconstruct how it was decided, when, or against which threshold.
sourceDeclaration is the field teams drop and the one an auditor asks about. It's the difference between "the platform told us she's over 18" and "the platform told us she typed that she's over 18."
With the record in that shape, the gate becomes one function instead of logic scattered through signup code:
A boolean can't support what follows from this shape. Re-checks become possible, which Ofcom asks for. Threshold changes become a migration, not a rewrite: when the UK adds 16 alongside 18, you already know which users were only ever checked against 13. And revocation becomes an event you can apply, since Apple's RESCIND_CONSENT notification arrives server-side and should update this record, not just lock a screen.
One more rule worth encoding: Google says Play Age Signals data may be used only "to provide age-appropriate content and experiences in compliance with laws," and not for "advertising, marketing, user profiling, or analytics," with loss of API access and app takedown as the consequences. If this attribute is readable by your growth stack, you've built a policy violation into your schema.
What should you decide this week?
Pick the thresholds you actually need to assert, then design the record before you shortlist a vendor. The coalition wants a buyer to show that age verification beyond self-disclosure exists, and showing it is a records problem. You can only show what you wrote down.
The Character.AI filing and the Discord breach teach the same lesson from opposite ends. One company couldn't say which of its users were children; the other kept the proof it used to say so, and it ended up in a ransom demand. Ask the question at signup. Keep the answer, the method and the time. Don't keep the document.
If you use AuthKit, keep the age record in your own database keyed on the WorkOS user ID. AuthKit's identity linking attaches every sign-in method tied to the same verified email (password, Google, Magic Auth, SSO) to one user, so the age result follows that user across all of them, and WorkOS never holds the evidence. A sign-in under a different email creates a new user with no age record, so treat it as unchecked until it goes through your flow.