On Sun, 1 Mar 2026 14:02:56 -0800
Jamie Null <lav@lavender.earth> wrote:
> On 2026-03-01 12:42, Aaron Rainbolt wrote:
> > On Sun, 1 Mar 2026 15:12:09 -0500
> > "Vincent F. Heuser Jr." <vheuser@heuserlawoffice.com> wrote:
> >
> >> On 2026/03/01 14: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 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 distributions are also
> >>> investigating what to do with this, and the law requires us 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 "account setup". The OS is also expected to allow users to set
> >>> the user's age if they didn't already provide it (because the OS
> >>> was installed before the law went into effect), and it needs to
> >>> provide an API somewhere so 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", ">= 13
> >>> and < 16", ">= 16 and < 18", and ">= 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 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
> >>> 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 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
> >>> 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 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:
> >>>
> >>> <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object
> >>> Introspection 1.0//EN"
> >>> "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
> >>> <node name="/org/freedesktop/AgeVerification1"> <interface
> >>> name="org.freedesktop.AgeVerification1"> <method name="SetAge">
> >>> <arg type="s" name="User" direction="in"/>
> >>> <arg type="u" name="YearsOfAge" direction="in"/>
> >>> </method>
> >>> <method name="SetDateOfBirth">
> >>> <arg type="s" name="User" direction="in"/>
> >>> <arg type="s" name="Date" direction="in"/>
> >>> </method>
> >>> <method name='GetAgeBracket'>
> >>> <arg type="s" name="User" direction="in"/>
> >>> <arg type="u" name="AgeBracket" direction="out"/>
> >>> </method>
> >>> </interface>
> >>> </node>
> >>>
> >>> * The 'User' argument would, in all instances, be expected to be
> >>> the UNIX account username of the user in question. This user
> >>> account must not be a system account (i.e. its UID must fall
> >>> between UID_MIN and UID_MAX as defined by /etc/login.defs). If a
> >>> user is specified that does not exist or whose UID is out of
> >>> range, these methods will return the error
> >>> 'org.freedesktop.AgeVerification1.Error.NoSuchUser'. If the
> >>> specified user is not the same as the user making the method call,
> >>> and the user making the method call is not root, these methods
> >>> will return the error
> >>> 'org.freedesktop.AgeVerification1.Error.PermissionDenied'.
> >>> * The 'YearsOfAge' argument of the 'SetAge' method should be an
> >>> unsigned integer specifying the age of the user in years at
> >>> the time of the method call. (The law specifically allows
> >>> providing simply an age value rather than a birth date if
> >>> desired.)
> >>> * The 'Date' argument of the 'SetDateOfBirth' method should be a
> >>> string in ISO8601 format (i.e. YYYY-MM-DD) indicating the day on
> >>> which the user was born. If the argument is invalid, the method
> >>> will return the error
> >>> 'org.freedesktop.AgeVerification1.Error.InvalidDate'.
> >>> * The 'AgeBracket' output argument of the 'GetAgeBracket' method
> >>> will be an unsigned integer between 1 and 4 inclusive, where 1
> >>> indicates that the user is under 13 years old, 2 indicates that
> >>> the user is at least 13 and under 16 years old, 3 indicates that
> >>> the user is at least 16 and under 18 years old, and 4 indicates
> >>> that the user is 18 years old or older. If no age has been
> >>> configured for the user yet, the method will return the error
> >>> '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 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 reason to do this would be for additional privacy, and
> >>> privacy-conscious users can simply lie about their age or the
> >>> age of the intended user. There isn't anything in the law (that I
> >>> can tell) that prevents the user from just saying "I'm 18" when
> >>> the prompt appears and going with it. This would also be really
> >>> difficult to implement outside of the context of
> >>> xdg-desktop-portal, and would probably only work with sandboxed
> >>> apps if it was implemented that way.
> >>> * UX for actually requesting the age from the user. IMO this is
> >>> out of scope for FreeDesktop; individual distros should see to it
> >>> that they prompt for the user's age or birth date at "account
> >>> setup" (whatever that happens to be defined as for the distro in
> >>> question), nudge the user to provide the information later on for
> >>> existing installations, etc. Furthermore, this mechanism needs to
> >>> work even on CLI-only installs and maybe even on server installs,
> >>> depending on how one defines "general purpose computing device"
> >>> (as specified by the law in question), so defining any specific
> >>> UX is likely infeasible. (If this is required on servers,
> >>> end-users will probably want to auto-provision the age
> >>> information somehow, and specifying how to do that in a
> >>> distribution-agnostic way is impossible given that Ubuntu uses
> >>> cloud-init, Fedora uses Kickstart and Ignition, etc.)
> >>> * Omitting the 'SetDateOfBirth' method. It can be lived without
> >>> legally, but without the method, it becomes difficult for
> >>> software that already records the user's date of birth to
> >>> accurately implement automatic age bracket adjustment as time
> >>> passes. This isn't a feature Kicksecure would use, but it's a
> >>> feature some projects might be interested in.
> >>>
> >>> Thanks for taking a look at this.
> >>>
> >>> --
> >>> Aaron
> >>>
> >>> [1]
> >>> https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=202520260AB1043
> >>> [2] https://leg.colorado.gov/bill_files/110990/download [3]
> >>> https://www.kicksecure.com/ [4] https://www.whonix.org/
> >>> [5]
> >>> https://www.freedesktop.org/wiki/Specifications/file-manager-interface/
> >>>
> >>
> >> By definition, not a Debian or Ubuntu problem:
> >> https://www.merriam-webster.com/dictionary/vendor
> >
> > I may have been incorrectly imprecise; the law linked says that "an
> > operating system provider shall" do the things needed to comply with
> > the title, and defines an operating system provider as "a person or
> > entity that develops, licenses, or controls the operating system
> > software on a computer, mobile device, or any other general purpose
> > computing device." "Vendor" is a term I mistakenly used, as far as I
> > can tell the law does not exclude operating systems that are offered
> > for free. Again though, as I stated, I am not a lawyer, so perhaps
> > I'm misunderstanding the meaning of the definition of "operating
> > system provider".
> >
> > --
> > Aaron
>
> Is there a reason this cannot be implemented as a separate package
> which can be selected through the installer?
Other than ease of integration, not to my awareness.
> The issue with building it into existing components is that while an
> "age verification" API might be required in some jurisdictions, there
> are others where providing this API could run afoul of privacy laws
> or is otherwise legally prohibited. Furthermore, should more
> jurisdictions decide to enact poorly-considered "age verification"
> laws with varying requirements as to what is disclosed, it would be
> easier to accommodate those jurisdictions' requirements this way.
Good point. Maybe integrating this into AccountsService isn't a good
idea, and having a standardized API that can have arbitrary
implementations is a better choice. Maybe another error,
'org.freedesktop.AgeVerification1.Error.NotApplicable' should be added
to the proposal too.
--
Aaron