On Sun, 1 Mar 2026 14:02:56 -0800 Jamie Null <[email protected]> wrote:
> On 2026-03-01 12:42, Aaron Rainbolt wrote: > > On Sun, 1 Mar 2026 15:12:09 -0500 > > "Vincent F. Heuser Jr." <[email protected]> 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
pgpYPz77dduvx.pgp
Description: OpenPGP digital signature

