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

--000000000000881b31064c0edfae--