Re: On the unfortunate need for an "age verification" API for legal compliance reasons in some U.S. states

Artur Manuel <[email protected]> Tue, 10 Mar 2026 03:33:56 +0000
Newsgroups gmane.linux.xdg.devel,gmane.linux.redhat.fedora.devel,gmane.linux.ubuntu.devel,gmane.linux.debian.devel.general,gmane.linux.debian.devel.legal,gmane.linux.redhat.fedora.legal
Message-ID <[email protected]>
10 Mar 2026 01:47:06 Jeremy Soller <[email protected]>:

> Hello everyone,
>
> My name is Jeremy Soller, and I am Principal Engineer at System76. We=20
> released a statement on Age Verification laws last Thursday that you=20
> can read here:
>
> https://blog.system76.com/post/system76-on-age-verification
>
> Our Founder and CEO, Carl Richell, was able to get a meeting with=20
> Senator Matt Ball today to discuss the Colorado version of the=20
> California bill, SB26-051. His statements after the meeting are as=20
> follows:
>
> https://floss.social/@[email protected]/116201429734101067
>
>> Today, I met with Colorado Senator Matt Ball, co-author of Colorado OS=
=20
>> Age Attestation Bill SB26-051.
>>
>> Sen. Ball suggested excluding open source software from the bill. This=
=20
>> appears to be a real possibility.
>>
>> Amendments are expected for the CA age attestation bill. It's my hope=20
>> we can move fast enough to influence excluding open source in the CA=20
>> bill amendments.
>>
>> No illusions, it's an uphill battle, but we have an open door to=20
>> advocate for the open source community.
>
> At this time, we are seeing what kinds of changes might be made to=20
> these laws before they become effective. I would not generally advise=20
> working on any technical solution when the laws are ambiguous and=20
> likely to be amended. In the best case, although I believe it is=20
> unlikely, open-source operating systems would not have any work to do=20
> at all. In the worst case, different jurisdictions may have conflicting=
=20
> laws.
>
> We and our users greatly value our privacy, and I would hope not to see=
=20
> over-eager work on a technical implementation that is heavy handed and=20
> potentially jurisdiction specific. We at System76 are also awaiting the=
=20
> legal opinions of other operating systems, like Ubuntu, and those would=
=20
> likely be valuable to all potentially affected operating systems.
>
> Thank you,
>
> --
> =C2=A0 Jeremy Soller
> =C2=A0 System76
> =C2=A0 Principal Engineer
> =C2=A0 [email protected]
>
> On Sun, Mar 1, 2026, at 12:48 PM, Aaron Rainbolt wrote:
>> Given that this is related to legal stuff, I should preface this by
>> saying I am not a lawyer.
>>
>> Recently, a new law was passed in California that requires OS vendors
>> to provide some limited info about a user's age via an API that
>> application distribution websites and application stores can use. [1]
>> Colorado seems to be working on a similar law. [2] The law will go=20
>> into
>> effect January 1, 2027, it is no longer a draft. I do quite a bit of
>> work with an OS vendor (working with the Kicksecure [3] and Whonix [4]
>> projects), and we aren't particularly interested in blocking everyone
>> in California and Colorado from using our OSes, so we're currently
>> looking into how to implement an API that will comply with the laws
>> while also not being a privacy disaster. Given that other=20
>> distributions
>> are also investigating what to do with this, and the law requires us=20
>> to
>> make a "good faith effort to comply with [the] title, taking into
>> consideration available technology", I figured it would be a good idea
>> to bring the issue here.
>>
>> At its core, the law seems to require that an "operating system"
>> (I'm guessing this would correspond to a Linux distribution, not an OS
>> kernel or userland) request the user's age or date of birth at=20
>> "account
>> setup". The OS is also expected to allow users to set the user's age=20
>> if
>> they didn't already provide it (because the OS was installed before=20
>> the
>> law went into effect), and it needs to provide an API somewhere so=20
>> that
>> app stores and application distribution websites can ask the OS "what
>> age bracket does this user fall into?" Four age brackets are defined,
>> "< 13", ">=3D 13 and < 16", ">=3D 16 and < 18", and ">=3D 18". It looks =
like
>> the API also needs to not provide more information than just the age
>> bracket data. A bunch of stuff is left unclear (how to handle servers
>> and other CLI-only installs, how to handle VMs, whether the law is=20
>> even
>> applicable if the primary user is over 18 since the law ridiculously
>> defines a user as "a child" while also defining "a child" as anyone
>> under the age of 18, etc.), but that's what we're given to deal with.
>>
>> The most intuitive place to put this functionality would be, IMO,
>> AccountsService. The main issue with that is that stable-release
>> distributions, and distributions based upon them, would be faced with
>> the issue of how to get an updated version of AccountsService=20
>> integrated
>> into their software repositories, or how to backport the appropriate
>> code. The law goes into effect on January 1, 2027, Debian Bookworm is
>> going to be supported by ELTS until July 30, 2033, and we don't yet
>> know if Debian will care enough about California's laws to want to
>> backport a new feature in AccountsService into Debian Bookworm (or=20
>> even
>> Trixie). Distributions based on Debian (such as Kicksecure and Whonix)
>> may still want to comply with the law though, so something using
>> AccountsService-specific APIs would be frustrating. Requiring a whole
>> separate daemon for the foreseeable future just for an age=20
>> verification
>> API would also be annoying.
>>
>> Another place the functionality could go is xdg-desktop-portal. This
>> one is a bit non-ideal for a couple of reasons; for one, the easiest
>> place to put the call would be in the Account portal, which returns
>> more information than the account's age bracket. This could=20
>> potentially
>> be considered non-compliant with the law, as it states that the
>> operating system shall "[s]end only the minimum amount of information
>> necessary to comply with this title". This also comes with the
>> backporting disadvantages of an AccountsService-based implementation.
>>
>> For this reason, I'd like to propose a "hybrid" approach; introduce a
>> new standard D-Bus interface, `org.freedesktop.AgeVerification1`, that
>> can be implemented by arbitrary applications as a distro sees fit.
>> AccountsService could implement this API so that newer versions
>> of distros will get the relevant features for free, while distros with
>> an AccountsService too old to contain the feature can implement it
>> themselves as a stop-gap solution.
>>
>> Taking inspiration from the File Manager D-Bus interface [5], I think
>> something like the following might work:
>>
>> =C2=A0=C2=A0=C2=A0 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Obje=
ct
>> Introspection 1.0//EN"
>> =C2=A0=C2=A0=C2=A0=C2=A0 "http://www.freedesktop.org/standards/dbus/1.0/=
introspect.dtd">
>> =C2=A0=C2=A0=C2=A0 <node name=3D"/org/freedesktop/AgeVerification1">
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <interface name=3D"org.freedesktop.AgeVer=
ification1">
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <method name=3D"SetAge">
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"s" n=
ame=3D"User" direction=3D"in"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"u" n=
ame=3D"YearsOfAge" direction=3D"in"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </method>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <method name=3D"SetDateOfBirt=
h">
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"s" n=
ame=3D"User" direction=3D"in"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"s" n=
ame=3D"Date" direction=3D"in"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </method>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <method name=3D'GetAgeBracket=
'>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"s" n=
ame=3D"User" direction=3D"in"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <arg type=3D"u" n=
ame=3D"AgeBracket" direction=3D"out"/>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </method>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </interface>
>> =C2=A0=C2=A0=C2=A0 </node>
>>
>> * The 'User' argument would, in all instances, be expected to be the
>> =C2=A0 UNIX account username of the user in question. This user account=
=20
>> must
>> =C2=A0 not be a system account (i.e. its UID must fall between UID_MIN a=
nd
>> =C2=A0 UID_MAX as defined by /etc/login.defs). If a user is specified th=
at
>> =C2=A0 does not exist or whose UID is out of range, these methods will
>> =C2=A0 return the error=20
>> 'org.freedesktop.AgeVerification1.Error.NoSuchUser'.
>> =C2=A0 If the specified user is not the same as the user making the meth=
od
>> =C2=A0 call, and the user making the method call is not root, these meth=
ods
>> =C2=A0 will return the error
>> =C2=A0 'org.freedesktop.AgeVerification1.Error.PermissionDenied'.
>> * The 'YearsOfAge' argument of the 'SetAge' method should be an
>> =C2=A0 unsigned integer specifying the age of the user in years at the t=
ime
>> =C2=A0 of the method call. (The law specifically allows providing simply=
 an
>> =C2=A0 age value rather than a birth date if desired.)
>> * The 'Date' argument of the 'SetDateOfBirth' method should be a=20
>> string
>> =C2=A0 in ISO8601 format (i.e. YYYY-MM-DD) indicating the day on which t=
he
>> =C2=A0 user was born. If the argument is invalid, the method will return=
=20
>> the
>> =C2=A0 error 'org.freedesktop.AgeVerification1.Error.InvalidDate'.
>> * The 'AgeBracket' output argument of the 'GetAgeBracket' method will=20
>> be
>> =C2=A0 an unsigned integer between 1 and 4 inclusive, where 1 indicates=
=20
>> that
>> =C2=A0 the user is under 13 years old, 2 indicates that the user is at=
=20
>> least
>> =C2=A0 13 and under 16 years old, 3 indicates that the user is at least =
16
>> =C2=A0 and under 18 years old, and 4 indicates that the user is 18 years=
=20
>> old
>> =C2=A0 or older. If no age has been configured for the user yet, the met=
hod
>> =C2=A0 will return the error
>> =C2=A0 'org.freedesktop.AgeVerification1.Error.AgeUndefined'.
>>
>> I propose that the exact way in which age information is stored by the
>> daemon should be left implementation-defined. For Kicksecure, the way
>> we implement it will almost certainly store only the age bracket and
>> require users to explicitly reconfigure their age once they are old
>> enough to move from one age bracket to another. Other implementations
>> may choose to store the date of birth or the age and date on which the
>> age was set so that they can automatically update the age bracket as
>> time passes. This interface will be provided *on the system bus* (NOT
>> the session bus!), and the D-Bus service that provides these services
>> should run as root. The file containing the user-to-age mappings=20
>> should
>> be owned by root and should not be world-readable, to prevent leaking
>> the user's specific age to malicious applications.
>>
>> Some things I did think about when writing the above but ultimately
>> decided to not propose:
>>
>> * Detailed permission gating for the 'GetAgeBracket' method. The only
>> =C2=A0 reason to do this would be for additional privacy, and
>> =C2=A0 privacy-conscious users can simply lie about their age or the age=
 of
>> =C2=A0 the intended user. There isn't anything in the law (that I can te=
ll)
>> =C2=A0 that prevents the user from just saying "I'm 18" when the prompt
>> =C2=A0 appears and going with it. This would also be really difficult to
>> =C2=A0 implement outside of the context of xdg-desktop-portal, and would
>> =C2=A0 probably only work with sandboxed apps if it was implemented that=
=20
>> way.
>> * UX for actually requesting the age from the user. IMO this is out of
>> =C2=A0 scope for FreeDesktop; individual distros should see to it that t=
hey
>> =C2=A0 prompt for the user's age or birth date at "account setup" (whate=
ver
>> =C2=A0 that happens to be defined as for the distro in question), nudge =
the
>> =C2=A0 user to provide the information later on for existing installatio=
ns,
>> =C2=A0 etc. Furthermore, this mechanism needs to work even on CLI-only
>> =C2=A0 installs and maybe even on server installs, depending on how one
>> =C2=A0 defines "general purpose computing device" (as specified by the l=
aw
>> =C2=A0 in question), so defining any specific UX is likely infeasible. (=
If
>> =C2=A0 this is required on servers, end-users will probably want to
>> =C2=A0 auto-provision the age information somehow, and specifying how to=
 do
>> =C2=A0 that in a distribution-agnostic way is impossible given that Ubun=
tu
>> =C2=A0 uses cloud-init, Fedora uses Kickstart and Ignition, etc.)
>> * Omitting the 'SetDateOfBirth' method. It can be lived without
>> =C2=A0 legally, but without the method, it becomes difficult for softwar=
e
>> =C2=A0 that already records the user's date of birth to accurately=20
>> implement
>> =C2=A0 automatic age bracket adjustment as time passes. This isn't a=20
>> feature
>> =C2=A0 Kicksecure would use, but it's a feature some projects might be
>> =C2=A0 interested in.
>>
>> Thanks for taking a look at this.
>>
>> --
>> Aaron
>>
>> [1]
>>=20
>> https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=3D=
202520260AB1043
>> [2] https://leg.colorado.gov/bill_files/110990/download
>> [3] https://www.kicksecure.com/
>> [4] https://www.whonix.org/
>> [5]
>>=20
>> https://www.freedesktop.org/wiki/Specifications/file-manager-interface/
>>
>> --
>> ubuntu-devel mailing list
>> [email protected]
>> Modify settings or unsubscribe at:
>> https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel

I appreciate that Sen. Ball is being as forgiving to open-source projects=
=20
as he is. Honestly, more people should proactively try to contact their=20
politicians regarding these laws. Could help prevent a lot more=20
frustration for both us and regular users.

Great work, both to you and Carl. Hopefully we can protect open source=20
from legal doom for more years to come.

Cheers as always,

--=20
Artur Manuel
amadaluzia