Re: On the unfortunate need for an "age verification" API for legal compliance reasons in some U.S. states
Danielle Foré <[email protected]> Mon, 2 Mar 2026 10:36:52 -0800
| Newsgroups | gmane.linux.xdg.devel,gmane.linux.debian.devel.general,gmane.linux.redhat.fedora.devel,gmane.linux.ubuntu.devel,gmane.linux.debian.devel.legal,gmane.linux.redhat.fedora.legal |
|---|---|
| Message-ID | <CADpqsky71cqskqrytiMJahyMd3cQa5_gFtq+6uvfvQtEmYzZ1A@mail.gmail.com> |
--000000000000881b31064c0edfae Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hey Aaron et al, I'm digging into this a bit more this morning and I found something really interesting in Apple's implementation. It seems that what they do is that apps will send an array containing 3 age gates and their API responds with two ints, a lower bound and upper bound. The values of the lower and upper bounds will be either -1 or the value of one of the gates you sent. Lower is the lowest age gate they exceed and upper is the highest age gate they are below. For example: I send the api an array of [9, 13, 16]. If the API responds [9, 16], the child is older than 9 but under 16. If the API responds [-1, 16], the child is under 9 If the API responds [16, -1], the child is over 16. Apps can also send -1 for the last two ints, which seems to help with sending only the minimum information. For example: I send the api an array of [16, -1, -1], the api responds with [-1, 16] to let me know the child is under 16 or [16, -1] to let me know the child is over 16. Their docs also say the system might respond with different values based on regulations in the region. So for example I send the api an array of [15, 16, 17] because I'm doing something nefarious, the api responds with either [13, 16] or [16, 18] to make sure it's returning a range and not an age. It seems pretty clever. They also have provisions for declining to share based on region etc. Full documentation here: https://developer.apple.com/documentation/declaredagerange/ On Sun, Mar 1, 2026 at 2:10=E2=80=AFPM Aaron Rainbolt <[email protected]= > wrote: > 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", ">=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 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=3D"/org/freedesktop/AgeVerification1"> <interface > > >>> name=3D"org.freedesktop.AgeVerification1"> <method name=3D"SetAge"> > > >>> <arg type=3D"s" name=3D"User" direction=3D"in"/> > > >>> <arg type=3D"u" name=3D"YearsOfAge" direction=3D"in"/> > > >>> </method> > > >>> <method name=3D"SetDateOfBirth"> > > >>> <arg type=3D"s" name=3D"User" direction=3D"in"/> > > >>> <arg type=3D"s" name=3D"Date" direction=3D"in"/> > > >>> </method> > > >>> <method name=3D'GetAgeBracket'> > > >>> <arg type=3D"s" name=3D"User" direction=3D"in"/> > > >>> <arg type=3D"u" name=3D"AgeBracket" direction=3D"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=3D2= 02520260AB1043 > > >>> [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 > --000000000000881b31064c0edfae Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Hey Aaron et al,<div><br></div><div>I'm digging into t= his a bit more this morning and I found something really interesting in App= le's implementation. It seems that what they do is that apps will send = an array containing 3 age gates and their API responds with two ints,=C2=A0= a lower bound and upper bound. The values of the lower and upper bounds wil= l be either -1 or the value of one of the gates you sent. Lower is the lowe= st age gate they exceed and upper is the highest age gate they are below. F= or example:</div><div><br></div><div>I send the api an array of [9, 13, 16]= .</div><div><br></div><div>If the API responds [9, 16], the child is older = than 9 but under 16.</div><div><div>If the API responds=C2=A0[-1, 16], the = child is under 9</div></div><div><div>If the API responds [16, -1], the chi= ld is over 16.</div><div><br></div><div>Apps can also send -1 for the last = two ints, which seems to help with sending only the minimum information. Fo= r example: I send the api an array of [16, -1, -1], the api responds=C2=A0w= ith [-1, 16] to let me know the child is under 16 or [16, -1] to let me kno= w the child is over 16.</div><div></div></div><div><br></div><div>Their doc= s also say the=C2=A0system might respond with different=C2=A0values based o= n regulations in the region. So for example I send the api an array of [15,= 16, 17] because I'm doing something nefarious, the api responds with e= ither [13, 16] or [16, 18] to make sure it's returning a range and not = an age.</div><div><br></div><div>It seems pretty clever. They also have pro= visions for declining to share based on region etc. Full documentation here= :=C2=A0<a href=3D"https://developer.apple.com/documentation/declaredagerang= e/">https://developer.apple.com/documentation/declaredagerange/</a></div></= div><br><div class=3D"gmail_quote gmail_quote_container"><div dir=3D"ltr" c= lass=3D"gmail_attr">On Sun, Mar 1, 2026 at 2:10=E2=80=AFPM Aaron Rainbolt &= lt;<a href=3D"mailto:[email protected]">[email protected]</a>> wro= te:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px = 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sun, 1 Ma= r 2026 14:02:56 -0800<br> Jamie Null <[email protected]> wrote:<br> <br> > On 2026-03-01 12:42, Aaron Rainbolt wrote:<br> > > On Sun, 1 Mar 2026 15:12:09 -0500<br> > > "Vincent F. Heuser Jr." <<a href=3D"mailto:vheuser@h= euserlawoffice.com" target=3D"_blank">[email protected]</a>> w= rote:<br> > >=C2=A0 =C2=A0<br> > >> On 2026/03/01 14:48 PM, Aaron Rainbolt wrote:=C2=A0 <br> > >>> Given that this is related to legal stuff, I should prefa= ce this<br> > >>> by saying I am not a lawyer.<br> > >>><br> > >>> Recently, a new law was passed in California that require= s OS<br> > >>> vendors to provide some limited info about a user's a= ge via an API<br> > >>> that application distribution websites and application st= ores can<br> > >>> use. [1] Colorado seems to be working on a similar law. [= 2] The<br> > >>> law will go into effect January 1, 2027, it is no longer = a draft.<br> > >>> I do quite a bit of work with an OS vendor (working with = the<br> > >>> Kicksecure [3] and Whonix [4] projects), and we aren'= t<br> > >>> particularly interested in blocking everyone in Californi= a and<br> > >>> Colorado from using our OSes, so we're currently look= ing into how<br> > >>> to implement an API that will comply with the laws while = also not<br> > >>> being a privacy disaster. Given that other distributions = are also<br> > >>> investigating what to do with this, and the law requires = us to<br> > >>> make a "good faith effort to comply with [the] title= , taking into<br> > >>> consideration available technology", I figured it wo= uld be a good<br> > >>> idea to bring the issue here.<br> > >>><br> > >>> At its core, the law seems to require that an "opera= ting system"<br> > >>> (I'm guessing this would correspond to a Linux distri= bution, not<br> > >>> an OS kernel or userland) request the user's age or d= ate of birth<br> > >>> at "account setup". The OS is also expected to = allow users to set<br> > >>> the user's age if they didn't already provide it = (because the OS<br> > >>> was installed before the law went into effect), and it ne= eds to<br> > >>> provide an API somewhere so that app stores and applicati= on<br> > >>> distribution websites can ask the OS "what age brack= et does this<br> > >>> user fall into?" Four age brackets are defined, &quo= t;< 13", ">=3D 13<br> > >>> and < 16", ">=3D 16 and < 18", an= d ">=3D 18". It looks like the API<br> > >>> also needs to not provide more information than just the = age<br> > >>> bracket data. A bunch of stuff is left unclear (how to ha= ndle<br> > >>> servers and other CLI-only installs, how to handle VMs, w= hether<br> > >>> the law is even applicable if the primary user is over 18= since<br> > >>> the law ridiculously defines a user as "a child"= ; while also<br> > >>> defining "a child" as anyone under the age of 1= 8, etc.), but<br> > >>> that's what we're given to deal with.<br> > >>><br> > >>> The most intuitive place to put this functionality would = be, IMO,<br> > >>> AccountsService. The main issue with that is that stable-= release<br> > >>> distributions, and distributions based upon them, would b= e faced<br> > >>> with the issue of how to get an updated version of Accoun= tsService<br> > >>> integrated into their software repositories, or how to ba= ckport<br> > >>> the appropriate code. The law goes into effect on January= 1, 2027,<br> > >>> Debian Bookworm is going to be supported by ELTS until Ju= ly 30,<br> > >>> 2033, and we don't yet know if Debian will care enoug= h about<br> > >>> California's laws to want to backport a new feature i= n<br> > >>> AccountsService into Debian Bookworm (or even Trixie).<br= > > >>> Distributions based on Debian (such as Kicksecure and Who= nix) may<br> > >>> still want to comply with the law though, so something us= ing<br> > >>> AccountsService-specific APIs would be frustrating. Requi= ring a<br> > >>> whole separate daemon for the foreseeable future just for= an age<br> > >>> verification API would also be annoying.<br> > >>><br> > >>> Another place the functionality could go is xdg-desktop-p= ortal.<br> > >>> This one is a bit non-ideal for a couple of reasons; for = one, the<br> > >>> easiest place to put the call would be in the Account por= tal,<br> > >>> which returns more information than the account's age= bracket.<br> > >>> This could potentially be considered non-compliant with t= he law,<br> > >>> as it states that the operating system shall "[s]end= only the<br> > >>> minimum amount of information necessary to comply with th= is<br> > >>> title". This also comes with the backporting disadva= ntages of an<br> > >>> AccountsService-based implementation.<br> > >>><br> > >>> For this reason, I'd like to propose a "hybrid&q= uot; approach;<br> > >>> introduce a new standard D-Bus interface,<br> > >>> `org.freedesktop.AgeVerification1`, that can be implement= ed by<br> > >>> arbitrary applications as a distro sees fit. AccountsServ= ice<br> > >>> could implement this API so that newer versions of distro= s will<br> > >>> get the relevant features for free, while distros with an= <br> > >>> AccountsService too old to contain the feature can implem= ent it<br> > >>> themselves as a stop-gap solution.<br> > >>><br> > >>> Taking inspiration from the File Manager D-Bus interface = [5], I<br> > >>> think something like the following might work:<br> > >>><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0<!DOCTYPE node PUBLIC "= -//freedesktop//DTD D-BUS Object<br> > >>> Introspection 1.0//EN"=C2=A0 <br> > >>> "<a href=3D"http://www.freedesktop.org/standards/dbu= s/1.0/introspect.dtd" rel=3D"noreferrer" target=3D"_blank">http://www.freed= esktop.org/standards/dbus/1.0/introspect.dtd</a>">=C2=A0 <br> > >>> <node name=3D"/org/freedesktop/AgeVerification1&q= uot;> <interface=C2=A0 <br> > >>> name=3D"org.freedesktop.AgeVerification1"> &= lt;method name=3D"SetAge">=C2=A0 <br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"s" name=3D"User" direction=3D"in"/><= br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"u" name=3D"YearsOfAge" direction=3D"in"= /><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</method><b= r> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<method name= =3D"SetDateOfBirth"><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"s" name=3D"User" direction=3D"in"/><= br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"s" name=3D"Date" direction=3D"in"/><= br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</method><b= r> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<method name= =3D'GetAgeBracket'><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"s" name=3D"User" direction=3D"in"/><= br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<arg ty= pe=3D"u" name=3D"AgeBracket" direction=3D"out"= ;/><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</method><b= r> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</interface><br> > >>>=C2=A0 =C2=A0 =C2=A0 =C2=A0</node><br> > >>><br> > >>> * The 'User' argument would, in all instances, be= expected to be<br> > >>> the UNIX account username of the user in question. This u= ser<br> > >>> account must not be a system account (i.e. its UID must f= all<br> > >>> between UID_MIN and UID_MAX as defined by /etc/login.defs= ). If a<br> > >>> user is specified that does not exist or whose UID is out= of<br> > >>> range, these methods will return the error<br> > >>> 'org.freedesktop.AgeVerification1.Error.NoSuchUser= 9;. If the<br> > >>> specified user is not the same as the user making the met= hod call,<br> > >>> and the user making the method call is not root, these me= thods<br> > >>> will return the error<br> > >>> 'org.freedesktop.AgeVerification1.Error.PermissionDen= ied'.<br> > >>> * The 'YearsOfAge' argument of the 'SetAge= 9; method should be an<br> > >>>=C2=A0 =C2=A0 =C2=A0unsigned integer specifying the age of= the user in years at<br> > >>> the time of the method call. (The law specifically allows= <br> > >>> providing simply an age value rather than a birth date if= <br> > >>> desired.)<br> > >>> * The 'Date' argument of the 'SetDateOfBirth&= #39; method should be a<br> > >>> string in ISO8601 format (i.e. YYYY-MM-DD) indicating the= day on<br> > >>> which the user was born. If the argument is invalid, the = method<br> > >>> will return the error<br> > >>> 'org.freedesktop.AgeVerification1.Error.InvalidDate&#= 39;.<br> > >>> * The 'AgeBracket' output argument of the 'Ge= tAgeBracket' method<br> > >>> will be an unsigned integer between 1 and 4 inclusive, wh= ere 1<br> > >>> indicates that the user is under 13 years old, 2 indicate= s that<br> > >>> the user is at least 13 and under 16 years old, 3 indicat= es that<br> > >>> the user is at least 16 and under 18 years old, and 4 ind= icates<br> > >>> that the user is 18 years old or older. If no age has bee= n<br> > >>> configured for the user yet, the method will return the e= rror<br> > >>>=C2=A0 =C2=A0 =C2=A0'org.freedesktop.AgeVerification1.= Error.AgeUndefined'.<br> > >>><br> > >>> I propose that the exact way in which age information is = stored by<br> > >>> the daemon should be left implementation-defined. For Kic= ksecure,<br> > >>> the way we implement it will almost certainly store only = the age<br> > >>> bracket and require users to explicitly reconfigure their= age once<br> > >>> they are old enough to move from one age bracket to anoth= er. Other<br> > >>> implementations may choose to store the date of birth or = the age<br> > >>> and date on which the age was set so that they can automa= tically<br> > >>> update the age bracket as time passes. This interface wil= l be<br> > >>> provided *on the system bus* (NOT the session bus!), and = the D-Bus<br> > >>> service that provides these services should run as root. = The file<br> > >>> containing the user-to-age mappings should be owned by ro= ot and<br> > >>> should not be world-readable, to prevent leaking the user= 's<br> > >>> specific age to malicious applications.<br> > >>><br> > >>> Some things I did think about when writing the above but<= br> > >>> ultimately decided to not propose:<br> > >>><br> > >>> * Detailed permission gating for the 'GetAgeBracket&#= 39; method. The<br> > >>> only reason to do this would be for additional privacy, a= nd<br> > >>>=C2=A0 =C2=A0 =C2=A0privacy-conscious users can simply lie= about their age or the<br> > >>> age of the intended user. There isn't anything in the= law (that I<br> > >>> can tell) that prevents the user from just saying "I= 'm 18" when<br> > >>> the prompt appears and going with it. This would also be = really<br> > >>> difficult to implement outside of the context of<br> > >>> xdg-desktop-portal, and would probably only work with san= dboxed<br> > >>> apps if it was implemented that way.<br> > >>> * UX for actually requesting the age from the user. IMO t= his is<br> > >>> out of scope for FreeDesktop; individual distros should s= ee to it<br> > >>> that they prompt for the user's age or birth date at = "account<br> > >>> setup" (whatever that happens to be defined as for t= he distro in<br> > >>> question), nudge the user to provide the information late= r on for<br> > >>> existing installations, etc. Furthermore, this mechanism = needs to<br> > >>> work even on CLI-only installs and maybe even on server i= nstalls,<br> > >>> depending on how one defines "general purpose comput= ing device"<br> > >>> (as specified by the law in question), so defining any sp= ecific<br> > >>> UX is likely infeasible. (If this is required on servers,= <br> > >>> end-users will probably want to auto-provision the age<br= > > >>> information somehow, and specifying how to do that in a<b= r> > >>> distribution-agnostic way is impossible given that Ubuntu= uses<br> > >>> cloud-init, Fedora uses Kickstart and Ignition, etc.)<br> > >>> * Omitting the 'SetDateOfBirth' method. It can be= lived without<br> > >>>=C2=A0 =C2=A0 =C2=A0legally, but without the method, it be= comes difficult for<br> > >>> software that already records the user's date of birt= h to<br> > >>> accurately implement automatic age bracket adjustment as = time<br> > >>> passes. This isn't a feature Kicksecure would use, bu= t it's a<br> > >>> feature some projects might be interested in.<br> > >>><br> > >>> Thanks for taking a look at this.<br> > >>><br> > >>> --<br> > >>> Aaron<br> > >>><br> > >>> [1]<br> > >>> <a href=3D"https://leginfo.legislature.ca.gov/faces/billT= extClient.xhtml?bill_id=3D202520260AB1043" rel=3D"noreferrer" target=3D"_bl= ank">https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id= =3D202520260AB1043</a><br> > >>> [2] <a href=3D"https://leg.colorado.gov/bill_files/110990= /download" rel=3D"noreferrer" target=3D"_blank">https://leg.colorado.gov/bi= ll_files/110990/download</a> [3]<br> > >>> <a href=3D"https://www.kicksecure.com/" rel=3D"noreferrer= " target=3D"_blank">https://www.kicksecure.com/</a> [4] <a href=3D"https://= www.whonix.org/" rel=3D"noreferrer" target=3D"_blank">https://www.whonix.or= g/</a><br> > >>> [5]<br> > >>> <a href=3D"https://www.freedesktop.org/wiki/Specification= s/file-manager-interface/" rel=3D"noreferrer" target=3D"_blank">https://www= .freedesktop.org/wiki/Specifications/file-manager-interface/</a><br> > >>>=C2=A0 =C2=A0 =C2=A0<br> > >><br> > >> By definition, not a Debian or Ubuntu problem:<br> > >> <a href=3D"https://www.merriam-webster.com/dictionary/vendor"= rel=3D"noreferrer" target=3D"_blank">https://www.merriam-webster.com/dicti= onary/vendor</a>=C2=A0 <br> > > <br> > > I may have been incorrectly imprecise; the law linked says that &= quot;an<br> > > operating system provider shall" do the things needed to com= ply with<br> > > the title, and defines an operating system provider as "a pe= rson or<br> > > entity that develops, licenses, or controls the operating system<= br> > > software on a computer, mobile device, or any other general purpo= se<br> > > computing device." "Vendor" is a term I mistakenly= used, as far as I<br> > > can tell the law does not exclude operating systems that are offe= red<br> > > for free. Again though, as I stated, I am not a lawyer, so perhap= s<br> > > I'm misunderstanding the meaning of the definition of "o= perating<br> > > system provider".<br> > > <br> > > --<br> > > Aaron=C2=A0 <br> > <br> > Is there a reason this cannot be implemented as a separate package<br> > which can be selected through the installer?<br> <br> Other than ease of integration, not to my awareness.<br> <br> > The issue with building it into existing components is that while an <= br> > "age verification" API might be required in some jurisdictio= ns, there <br> > are others where providing this API could run afoul of privacy laws<br= > > or is otherwise legally prohibited. Furthermore, should more<br> > jurisdictions decide to enact poorly-considered "age verification= "<br> > laws with varying requirements as to what is disclosed, it would be<br= > > easier to accommodate those jurisdictions' requirements this way.<= br> <br> Good point. Maybe integrating this into AccountsService isn't a good<br= > idea, and having a standardized API that can have arbitrary<br> implementations is a better choice. Maybe another error,<br> 'org.freedesktop.AgeVerification1.Error.NotApplicable' should be ad= ded<br> to the proposal too.<br> <br> --<br> Aaron<br> </blockquote></div> --000000000000881b31064c0edfae--