<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="lib/rfc2629.xslt"?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes"?>
<?rfc subcompact="no" ?>
<?rfc linkmailto="no" ?>
<?rfc editing="no" ?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc-ext allow-markup-in-artwork="yes" ?>
<?rfc-ext include-index="no" ?>

<rfc ipr="trust200902"
     category="exp"
     submissionType="IETF"
     docName="draft-thierry-cap-uris-00"
     xmlns:xi="http://www.w3.org/2001/XInclude">
  <front>
    <title>Capability URIs and IRIs</title>

    <author initials="P." surname="Thierry" fullname="Pierre Thierry">
      <organization>Comonad Dev</organization>
      <address>
        <email>pierre@comonad.dev</email>
      </address>
    </author>

    <date day="20" month="09" year="2026" />
    <keyword>capabilities</keyword>
    <keyword>authorization</keyword>

    <abstract>
      <t>
        This specification describes several URI schemes to safely embed capabilities within URIs.
      </t>
    </abstract>

  </front>

  <middle>
    <section anchor="intro" title="Introduction">
      <section title="Rationale">
        <t>
	  The research on access control has shown that between the two major paradigms of access
	  control, access control lists (ACLs) are less expressive and usually open the possibility
	  of confused deputy attacks, which include some the most problematic attack surfaces of the
	  Web, like XSS and CSRF (see <xref target="aclsdont" format="title"/>). The ambient
	  authority inherent to ACLs is also often critical in enabling privilege escalation, making
	  one security flaw vastly more damaging.
	</t>
	<t>
	  The other paradigm, capability-based security, combines designation and authority, making
	  it possible to prevent confused deputy attacks and create new patterns of access control,
	  including composable security policies and safe delegation mechanisms. (see <xref
	  target="capmyths" format="title"/>)
	</t>
	<t>
	  HTTP URIs could be used as capabilities, but as HTTP URIs are not treated as sensitive
	  data by most systems, except for their authorization part (but the classical format
	  <tt>login:password</tt> has been deprecated since, see <xref target="RFC3986"/>, section
	  3.2.1), it opens up the possibility that capabilities would get leaked in various
	  problematic places, including being stored in server logs and shown in browser address
	  bars.
	</t>
	<t>	  
	  This specification describes URI schemes that make it possible to safely encode
	  capabilities as URIs and IRIs (see <xref target="RFC3987"/>) by combining an existing URI
	  or IRI and some authorization data into a URI or IRI, called capability-URI (for
	  readability, we don't distinguish capability-URIs and capability-IRIs, as they don't have
	  different security properties).
	</t>
      </section>

      <section title="Architectural benefits">
	<t>
	  These URIs and IRIs also deliver on the promises of several architectural decisions at the
	  core of the World Wide Web. <xref target="webarch"/> notes that
	</t>
	<blockquote>
	  It is a strength of Web Architecture that links can be made and shared; a user who has
	  found an interesting part of the Web can share this experience just by republishing a
	  URI.
	</blockquote>
	<t>
	  When authority is separated from designation, sharing a link is often not enough. And
	  several platforms only let their users share content among themselves. When the only tool
	  of access control is user identity, it is logical that you can only share with another
	  user. But fined grained capabilities make it possible again to share "an interesting part
	  of the Web".
	</t>
	<t>
	  Capability-URIs are also a better fit than identity-based authorization in REST APIs
	  (see <xref target="rest" format="title"/>, especially chapter 5). The hypermedia nature of
	  REST means that a payload may contain state transitions going to a variety of different
	  servers and in the context of identity-based authorization, it is unclear what credentials
	  should be used where and it creates the risk of using some credentials with the wrong
	  server, possibly leaking credentials to an untrusted system.
	</t>
	<t>
	  But if a REST server uses capability-URIs in the state transitions, the client knows with
	  certainy which credentials to use for each request, and each capability-URI can hold the
	  bare minimum of authority needed to trigger just that transition (see <xref
	  target="attenuation">Attenuation</xref>).
	</t>
	<t>
	  Capability-URIS also give the server more control over the trade-off between safety and
	  latency: when the client should be able to trigger a state transition often and/or over
	  some period of time, the server can embed a long-lived authorization in that state
	  transition with only the authority for that transition. It makes the capability easier to
	  reuse by a malicious agent, but with a very limited attack surface. On the other hand,
	  whenever some state transitions require that the client be very strictly verified to be
	  the right one, capabilities could have a very short TTL and the client would need to renew
	  them by requesting again the resource where they appeared.
	</t>
      </section>

      <section title="Conventions and Terminology">
        <t>
          The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
          NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as
          described in <xref target="BCP14"/>.
        </t>
      </section>
      <section title="Syntax Notation">
	<t>This specification uses the Augmented Backus-Naur Form (ABNF) notation of <xref
	target="RFC5234"/>.</t>
      </section>

      <section title="Prior work">
	<t>
	  The first use of URIs as capabilities was in the Waterken project, with <xref
	  target="web-key" format="none">web-keys</xref>, which placed an unguessable token in the
	  fragment of an <tt>https</tt> URI, and <xref target="yurl" format="none">YURLs</xref>,
	  with the <tt>httpy</tt> URI scheme, which introduced the <xref
	  target="y-property">Y-property</xref>.
	</t>
	<t>
	  Introducing a new URI scheme proved to be difficult with Web browsers at the time, so the
	  Waterken project ended up using <tt>https</tt> URIs with the fingerprint for the
	  Y-property embedded in the host.
	</t>
	<t>
	  Recently, several proposals were made about embedding capabilities as URIs with a new URI
	  scheme (see <xref target="ack">acknoledgements</xref>).
	</t>
	<t>
	  While this specification describes new URI schemes, the principle of web-keys remain a
	  useful alternative in use cases where using the new schemes is not possible, and it can
	  interoperate with capability-URIs. <xref target="web-key-desc"/> explains the basic
	  mechanism of web-keys and <xref target="web-cap"/> their evolution with capability-URIs.
	</t>
      </section>
    </section>

    <section title="The capability schemes" anchor="schemes">
      <section title="Principle of operation">
	<t>
	  When a capability-URI-aware HTTP agent (like a browser or library) is asked to make an
	  HTTP request to a resource identified by a capability-URI (with parameters like the method
	  or the request body), it extracts from that capability-URI the authorization data and the
	  request target, prepares the HTTP request with the user-given parameters but augments the
	  connection establishment and the request headers based on the authorization data of the
	  capability-URI.
	</t>
	<t>
	  In the following example, it puts the bearer token in the <tt>Authorization</tt> header
	  with the <tt>Bearer</tt> authorization scheme <xref target="RFC6750"/>:
	</t>
	<t><figure><artwork>
http.post("cap-https://bt=AViRTF9ppWiAtdnpVtVHDQ@example.com/foo", body="bar",
  headers={"Content-Type": "text/plain"})
	</artwork></figure></t>
	<t>would produce the following HTTP/1.1 <xref target="RFC9112"/> request:</t>
	<t><figure><artwork>
POST /foo HTTP/1.1
Host: example.com
Content-Type: text/plain
Authorization: Bearer AViRTF9ppWiAtdnpVtVHDQ

bar
	</artwork></figure></t>
	<t>or the following HTTP/2 <xref target="RFC9113"/> or HTTP/3 <xref target="RFC9114"/>
	request:</t>
	<t><figure><artwork>
HEADERS
  + END_HEADERS
    :method = POST
    :scheme = cap-https
    :authority = example.com
    :path = /foo
    content-type = text/plain
    authorization = Bearer AViRTF9ppWiAtdnpVtVHDQ

DATA
  + END_STREAM
bar
	</artwork></figure></t>
	<t>
	  Each URI scheme corresponds to an existing HTTP URI scheme, extended with rich
	  authorization data. In a target capability-URI, except for the <tt>userinfo</tt> component
	  which maps to the capability-URI's <tt>authorization</tt> component, every component has
	  the same syntax and semantics than the corresponding URI scheme (and maps to the same
	  request components, headers and pseudo-headers).
	</t>
	<table>
	  <thead><tr><th>Capability URI scheme</th><th>Corresponding URI
	  scheme</th><th/></tr></thead>
	  <tbody>
	    <tr><td><tt>cap-http</tt></td><td><tt>http</tt> <xref target="RFC9110"/></td><td>(see
	    <xref target="notls" format="title"/> about the security considerations)</td></tr>
	    <tr><td><tt>cap-https</tt></td><td><tt>https</tt> <xref
	    target="RFC9110"/></td><td/></tr>
	    <tr><td><tt>cap-ws</tt></td><td><tt>ws</tt> <xref target="RFC6455"/></td><td>(see <xref
	    target="notls" format="title"/> about the security considerations)</td></tr>
	    <tr><td><tt>cap-wss</tt></td><td><tt>wss</tt> <xref target="RFC6455"/></td><td/></tr>
	  </tbody>
	</table>
	<t>
	  As far as the capability-URI-aware agent is concerned, the URI of the designated resource
	  MUST NOT be the embedded HTTP URI, but the capability-URI (the retrieval URI is one source
	  for a base URI).
	</t>
      </section>

      <section title="Relative URI references">
	<t>
	  The normal algorithm from <xref target="RFC3986"/> (section 5.2) applies to relative
	  references, which means that except for network-path references with a userinfo component,
	  relative references reuse the same authorization data used to retrieve the resource
	  representation where they appear.
	</t>
	<t>
	  For that reason, the capability schemes include a dedicated syntax to use a relative path
	  with a different token: <tt>cap-https:bt=NVW9YpUuEkZ367AyA-3MZw@./bar</tt>. Note that when
	  such a relative capability-URI is parsed by a generic URI parser, the whole content after
	  the scheme will match the <tt>path-rootless</tt> rule of <xref target="RFC3986"/> (and the
	  token won't be parsed by the <tt>authority</tt> rule).
	</t>
	<t>
	  To make a relative reference with an absolute path, a network-path reference can be used:
	  <tt>//D-nX3h-tDq_VtaYQKYYlDw@/baz</tt>. If there could be ambiguity whether the base URI
	  is a capability-URI, it is valid for capability-URIs to have an empty host, which creates
	  a URI that is equivalent to a network-path reference, but with the scheme specified:
	  <tt>cap-https://bt=D-nX3h-tDq_VtaYQKYYlDw@/baz</tt>.
	</t>
	<t>
	  These relative capability-URI, like relative URI references, refer to a target
	  capability-URI.
	</t>
      </section>

      <section title="Definitions">
	<t>
	  The four URI schemes are specified by the rules
	  <list style="symbol">
	    <t><tt>cap-http-uri</tt></t>
	    <t><tt>cap-https-uri</tt></t>
	    <t><tt>cap-ws-uri</tt></t>
	    <t><tt>cap-wss-uri</tt></t>
	  </list>
	</t>
	<t>
	  The corresponding IRIs are specified by the rules
	  <list style="symbol">
	    <t><tt>cap-http-iri</tt></t>
	    <t><tt>cap-https-iri</tt></t>
	    <t><tt>cap-ws-iri</tt></t>
	    <t><tt>cap-wss-iri</tt></t>
	  </list>
	</t>
	<t><figure><artwork>
cap-http-uri        = "cap-http" ":" cap-path [ "?" query ] [ "#" fragment ]
cap-https-uri       = "cap-https" ":" cap-path [ "?" query ] [ "#" fragment ]
cap-ws-uri          = "cap-ws" ":" cap-path [ "?" query ]
cap-wss-uri         = "cap-wss" ":" cap-path [ "?" query ]
cap-path            = absolute-cap-path / relative-cap-path
absolute-cap-path   = "//" authorization "@" host [ ":" port ] path-abempty
relative-cap-path   = authorization "@" path-rel
path-rel            = segment-rel "/" path-rootless
authorization       = [ param *( ";" param ) ]
param               = 1*param-char
param-char          = unreserved / pct-encoded / param-delims
param-delims        = "!" / "$" / "&amp;" / "'" / "(" / ")" / "*" / "+" / "," / "=" / ":"
bearer-token-param  = "bt=" token
token               = 1*param-char
token-format-param  = [ "*" ] "tf=" token-format
token-format        = 1*param-char
y-cert-param        = "yc=" y-cert-alg ":" y-cert-hash
y-cert-alg          = 1*unreserved
y-cert-hash         = base32
segment-rel         = "." / ".."
base32              =  "A" / "B" / "C" / "D" / "E" / "F" / "G" / "H" / "I" / "J" / "K" 
base32              =/ "L" / "M" / "N" / "O" / "P" / "Q" / "R" / "S" / "T" / "U" / "V" 
base32              =/ "W" / "X" / "Y" / "Z" / "2" / "3" / "4" / "5" / "6" / "7"

cap-http-iri        = "cap-http" ":" cap-ipath [ "?" iquery ] [ "#" ifragment ]
cap-https-iri       = "cap-https" ":" cap-ipath [ "?" iquery ] [ "#" ifragment ]
cap-ws-iri          = "cap-ws" ":" cap-ipath [ "?" iquery ]
cap-wss-iri         = "cap-wss" ":" cap-ipath [ "?" iquery ]
cap-ipath           = absolute-cap-ipath / relative-cap-ipath
absolute-cap-ipath  = "//" iauthorization "@" ihost [ ":" port ] ipath-abempty
relative-cap-ipath  = iauthorization "@" ipath-rel
ipath-rel           = isegment-rel "/" ipath-rootless
iauthorization      = [ iparam *( ";" iparam ) ]
iparam              = 1*param-ichar
param-ichar         = iunreserved / pct-encoded / param-delims
bearer-token-iparam = "bt=" itoken
itoken              = 1*param-ichar
	</artwork></figure></t>
	<t>
	  Note that the rule <tt>param-delims</tt> corresponds to the rule <tt>sub-delims</tt> (see
	  <xref target="RFC3986"/>, section 2.2), minus the <tt>";"</tt> alternative, plus the
	  <tt>":"</tt> alternative.
	</t>
	<t>
	  The definitions of the following rules are adopted from the generic syntax of URIs and
	  IRIs:
	</t>
	<t><figure><artwork>
host           = &lt;host, see [RFC3986], Section 3.2.2>
port           = &lt;port, see [RFC3986], Section 3.2.3>
path-abempty   = &lt;path-abempty, see [RFC3986], Section 3.3>
path-rootless  = &lt;path-rootless, see [RFC3986], Section 3.3>
unreserved     = &lt;unreserved, see [RFC3986], Section 2.3>
pct-encoded    = &lt;pct-encoded, see [RFC3986], Section 2.1>
query          = &lt;query, see [RFC3986], Section 3.4>
fragment       = &lt;fragment, see [RFC3986], Section 3.5>

ihost          = &lt;ihost, see [RFC3987], Section 2.2>
iport          = &lt;iport, see [RFC3987], Section 2.2>
ipath-abempty  = &lt;ipath-abempty, see [RFC3987], Section 2.2>
ipath-rootless = &lt;ipath-rootless, see [RFC3987], Section 2.2>
iunreserved    = &lt;iunreserved, see [RFC3987], Section 2.2>
iquery         = &lt;iquery, see [RFC3987], Section 2.2>
ifragment      = &lt;ifragment, see [RFC3987], Section 2.2>
	</artwork></figure></t>
	<t>
	  If the capability-URI has an <tt>absolute-cap-path</tt> where the <tt>host</tt> component
	  is empty or an <tt>absolute-cap-ipath</tt> where the <tt>ihost</tt> component is empty,
	  the URI is relative and is valid only if there is a known base URI (see <xref
	  target="RFC3986"/>, section 5.1). Resolving this relative capability-URI consists in
	  creating a target capability-URI where every component is taken from the relative
	  capability-URI, except the host, taken from the base URI.
	</t>
	<t>
	  If the capability-URI has a <tt>relative-cap-path</tt> or <tt>relative-cap-ipath</tt>,
	  resolving it consists in creating a target capability-URI where every component is taken
	  from the URI produced by resolving the relative reference present in the <tt>path-rel</tt>
	  or <tt>path-irel</tt> component, except the <tt>authorization</tt> or
	  <tt>iauthorization</tt> component, taken from the <tt>authorization</tt> or
	  <tt>iauthorization</tt> component of the relative capability-URI.
	</t>
      </section>

      <section title="Parameters">
	<t>
	  The <tt>authorization</tt> or <tt>iauthorization</tt> component of the capability-URI is
	  made of a sequence of parameters. This specification defines three such parameters, but a
	  future version can define more parameters, to support different authorization mechanisms,
	  or deprecate exisiting ones.
	</t>
	<t>
	  An application that doesn't implement some parameter MUST NOT make a request for a
	  capability-URI containing that parameter, except if that parameter's handling is
	  optional. If a parameter's handling is optional, it MUST begin with the character
	  <tt>*</tt>. If a parameter's handling is not optional, it MUST NOT begin with the
	  character <tt>*</tt>.
	</t>

	<section title="Bearer token">
	  <t>
	    When the <tt>bearer-token-param</tt> (in a URI) or <tt>bearer-token-iparam</tt> (in an
	    IRI) component is present, the request MUST contain an <tt>Authorization</tt> header
	    containing the <tt>token</tt> or <tt>itoken</tt> component as a bearer token used with
	    the <tt>Bearer</tt> authorization scheme (<xref target="RFC6750"/>).
	  </t>	 
	  <t>
	    When the <tt>bearer-token-param</tt> or <tt>bearer-token-iparam</tt> component is
	    absent, the request MUST NOT contain such an <tt>Authorization</tt> header with an empty
	    bearer token or one created from another source than the capability-URI's
	    parameters. Another parameter MAY add an <tt>Authorization</tt> header, including one
	    using the <tt>Bearer</tt> authorization scheme.
	  </t>
	  <t>
	    Examples:
	    <list style="symbols">
	      <t><tt>cap-https://<strong>bt=7w66swRJlKme6P3mXY3qww</strong>@foo.io</tt></t>
	      <t><tt>cap-https://<strong>bt=disallow-hacksaw-repaint-unguarded</strong>@bar.app/welcome</tt></t>
	      <t><tt>cap-wss://<strong>bt=mugol-majup-mupul-tizaj</strong>@baz.net/updates</tt></t>
	      <t><tt>cap-https://<strong>bt=衛停烈央察燒迅境若印洲刻</strong>@quux.com/login</tt></t>
	    </list>
	  </t>
	  <t>
	    When a capability-IRI contains a bearer token with characters outside US-ASCII, they
	    SHOULD be encoded as UTF-8 for the HTTP header, as the valid characters for
	    <tt>itoken</tt> encoded in UTF-8 are also valid for the <tt>field-vchar</tt> rule of
	    HTTP.
	  </t>
	</section>

	<section anchor="token-format" title="Token format">
	  <t>
	    When the <tt>token-format-param</tt> component is present, it gives the format used for
	    the bearer token.
	  </t>
	  <t>
	    This specification defines one value for <tt>token-format</tt> but a future version can
	    define more values or deprecate exisiting ones:
	  </t>
	  <table>
	    <thead><tr><th><tt>token-format</tt></th><th>Token format</th></tr></thead>
	    <tbody>
	      <tr><td><tt>bisc</tt></td><td>Biscut (see <xref target="biscuit"/>)</td></tr>
	    </tbody>
	  </table>
	  <t>
	    Example:
	    <list style="symbols">
	      <t><tt>cap-https://bt=EokBCh8KBmFjdGlvbhgDIggKBggCEgIQeyIJCgcIgAgSAhgAEiQIABIgncUlEtlWvSDNfM3zZF1i7uA0FipKD48IAKga_AlY3E0aQHJGTX-BrG0UwWHFFT231A0JEBtMWVBgKS5pUdMsISTjRH9DKY9PcFhQ2TqczdhGar8D6NCiZIoDeQvrZtkHJgwiIgog4qv2B3AC4VhoLybiDGxobq-POPtW_JxhRlRLjDJY7DM=;<strong>*tf=bisc</strong>@foo.io</tt></t>
	      <t><tt>cap-https://bt=EokBCh8KBmFjdGlvbhgDIggKBggCEgIQeyIJCgcIgAgSAhgAEiQIABIg32JaSzOOkDZeLRbnfN5qRQ0fPmT7fFaVzQ96zVffuzYaQOyfgWJUTAuJtuIgI8Y8ToW7mGPsQztQQ_WWHIzJMH1B6yCtncRiaBtAn9yYRuZ62JFiDYp8RyRmM3PPdETlwAIiIgog25_3GfCiu_5kjg-dEq05B7WY5IcoNFAo8P8s1XHlAIU=;<strong>tf=bisc</strong>@foo.io</tt></t>
	    </list>
	  </t>
	  <t>
	    This parameter's handling can be optional (if it starts with the <tt>*</tt>
	    character). An application SHOULD make this parameter's handling mandatory if actions
	    like <xref target="revocation">revocation</xref> and <xref
	    target="attenuation">attenuation</xref> of the capability-URI are not possible without
	    it.
	  </t>
	</section>

	<section title="Y-property certificate">
	  <t>
	    This parameter enables the <xref target="y-property" format="none">Y-property</xref>.
	  </t>
	  <t>
	    When the <tt>y-cert-param</tt> component is present, the client MUST check during TLS
	    handshake that in one X.509 certificate in the certificate chain of the server, the DER
	    encoding of the <tt>SubjectPublicKeyInfo</tt> field (see <xref target="RFC3279"/>),
	    hashed with the algorithm <tt>y-cert-alg</tt> and encoded in base32 (see <xref
	    target="RFC4648"/>, section 6) corresponds to <tt>y-cert-hash</tt>, or abort the TLS
	    handshake with a <tt>bad_certificate</tt> alert (see <xref target="RFC9846"/>, section
	    6.2). As the size of the hash is known, the base32 encoding MUST NOT contain padding.
	  </t>
	  <t>
	    This parameter MUST NOT be present in a <tt>cap-http</tt> or <tt>cap-ws</tt> URI, where
	    it wouldn't make sense.
	  </t>
	  <t>
	    This specification defines one value for <tt>y-cert-alg</tt> but a future version can
	    define more values or deprecate exisiting ones:
	  </t>
	  <table>
	    <thead><tr><th><tt>y-cert-alg</tt></th><th>Hashing algorithm</th></tr></thead>
	    <tbody>
	      <tr><td><tt>sha256</tt></td><td>SHA-256 (see <xref target="RFC6234"/>)</td></tr>
	    </tbody>
	  </table>
	  <t>
	    This parameter MAY be used without any other, to get the benefits of the Y-property even
	    in a URI that doesn't combine designation and authority.
	  </t>
	  <t>
	    Examples:
	    <list style="symbols">
	      <t><tt>cap-https://<strong>yc=sha256:OHYQO7NTO76XXDLIHAG2M35GQI4KGA5SSEN4W5YLHMVEEZUTZ6CA</strong>@foo.io/public/doc</tt></t>
	      <t><tt>cap-https://<strong>yc=sha256:HBRWGMZTG4ZDIN3DHE3TQYLEMQYTOODCGZRWGZDGMIYDAMJZMYFA</strong>;bt=NvjXBbwz6YlkI-nYIlhH5w@bar.app/welcome</tt></t>
	    </list>
	  </t>
	  <t>
	    base32 is used because it is more resilient to transcription, leaving few possible
	    ambiguities between the characters of the alphabet. To account for the possibility of
	    erroneous transcription, the following characters not present in base32's alphabet
	    SHOULD be substituted:
	  </t>
	  <table>
	    <thead><tr><th><tt>invalid characteur</tt></th><th>substitution</th></tr></thead>
	    <tbody>
	      <tr><td><tt>0</tt></td><td>O</td></tr>
	      <tr><td><tt>1</tt></td><td>I</td></tr>
	      <tr><td><tt>8</tt></td><td>B</td></tr>
	    </tbody>
	  </table>
	</section>
      </section>
    </section>

    <section anchor="web-cap" title="Web-caps">
      <t>
	While it can somtimes be straightforward to update frontend and backend code to be able to
	handle new URI schemes, their adoption by browsers is likely to take time. Also, backward
	compatibility with legacy browsers can be paramount.
      </t>
      <t>
	This specification describes a way to embed a capability in a legacy <tt>https</tt> URI, for
	its use in resource representations handled by a web browser, called web-caps. Web-caps are
	a direct evolution of <xref target="web-key-desc">web-keys</xref>.
      </t>
      <t>
	A web-cap is a <tt>https</tt> URI where the fragment is a <tt>cap-https</tt> URI. This
	capability-URI MUST NOT contain a <tt>host</tt> or <tt>ihost</tt> component, it MUST be a
	relative capability-URI with a <tt>cap-https</tt> scheme. The <tt>https</tt> URI without its
	fragment is called the trampoline URI, and it is the base URI for the capability-URI.
      </t>
      <t>
	When the browser makes a request for the trampoline URI, the representation in the server's
	response SHOULD be a document with client-side code that will extract the capability-URI,
	resolve it, and replace the document in the browser with the result of requesting the
	capability-URI. A document that implementents these steps is called a trampoline document.
      </t>
      <t>
	When the server doesn't respond with a trampoline document, it MUST respond with an HTTP
	error or with a document showing an error message.
      </t>
      <t>
	Once loaded, a trampoline document MUST attempt to modify the browser's address bar to
	remove the fragment as soon as possible, to limit the possibility of an attacker to observe
	the capability-URI on the user's screen or with malicious client-side code (through the
	<tt>Location</tt> interface of the browser).
      </t>
      <t>
	A trampoline document is a critical piece of the Trusted Computing Base (TCB) for the system
	using it. As such, a trampoline document SHOULD be as minimal as possible and SHOULD be
	audited with the most thorough methods available. A trampoline document MUST NOT load any
	external resources. Any request it makes apart from the request for the capability-URI may
	compromize the safety of that capability, even in indirect ways, so any stylesheet, image,
	or executable code MUST be embedded as data in the document, either as regular content (like
	a <tt>&lt;style&gt;</tt> or <tt>&lt;script&gt;</tt> element) or with a <tt>data:</tt> URL.
	To minimize the surface attack, a trampoline document MUST be served with the following
	header:
	<list style="symbols">
	  <t><tt>Content-Security-Policy</tt> (see <xref
	target="csp"/>) with only the following directives:
	  <list style="symbols">
	    <t><tt>default-src 'none'</tt></t>
	    <t>hashes</t>
	  </list>
	  </t>
	</list>
      </t>
      <t>
	It is RECOMMENDED that the resource identified by a trampoline URI be effectively
	immutable. If any security issue is found with a trampoline document, it is called a
	compromised trampoline document, and any web-cap whose trampoline URI identifies a
	compromised trampoline document is called a trampoline-compromised web-cap. A compromised
	trampoline document SHOULD not be served anymore and an application SHOULD NOT generate
	trampoline-compromised web-caps. Any new web-caps SHOULD be issued with a new trampoline URI
	that identifies a new, fixed trampoline document. It is RECOMMENDED that any capability that
	is suspected to be reachable through a trampoline-compromised web-cap be revoked immediately
	(see <xref target="revocation"/>).
      </t>
      <t>
	To limit browsers requesting the trampoline document more than once, it is RECOMMENDED to
	serve the trampoline document with the following header:
	<list style="symbols">
	  <t><tt>Cache-Control</tt> with only the following directives:
	  <list style="symbols">
	    <t><tt>max-age=2147483648</tt>: this is the highest value that is likely to be widely
	    supported by caches and any cache not supporting numbers that big MUST consider any age
	    it cannot represent in memory to be that value (see <xref target="RFC9111"/>, section
	    1.2.2).</t>
	    <t><tt>no-transform</tt></t>
	    <t><tt>immutable</tt> (see <xref target="RFC8246"/>)</t>
	  </list></t>
	</list>
      </t>
      <t>
	Because the fragment of a web-cap can be reliably identified as a capability-URI, a
	capability-URI-aware agent given a web-cap SHOULD resolve the capability-URI directly and
	request only that URI.
      </t>
      <t>
	Examples:
	<list style="symbols">
	  <t><tt>https://foo.io/trmp1#cap-https://ArB6Rj01ZS1_aN9rQjXT9Q@/obj</tt></t>
	  <t><tt>https://bar.app/webcap#cap-https://x8vSlccEDXcxv-7v7uXKog@/welcome</tt></t>
	</list>
      </t>
    </section>

    <section title="Security Considerations" anchor="sec">
      <section anchor="credentials" title="Capability-URIs are credentials">
	<t>
	  While the intent of this specification is for the most sensitive part of a capability-URI
	  to be the <tt>userinfo</tt> component of the generic URI syntax, any capability-URI MUST
	  be treated as a whole as a credential. As such, the default behavior of an application
	  using capability-URIs SHOULD be to never show a capability-URI unredacted.
	</t>
	<t>
	  Is is NOT RECOMMENDED to put any sensitive authorization data outside of the
	  <tt>userinfo</tt> component because the URI embedded in the capability-URI is vastly more
	  likely to end up being leaked, first and foremost in application and server logs.
	</t>
	<t>
	  It is NOT RECOMMENDED to rely on other applications to treat the <tt>userinfo</tt>
	  component as sensitive information and handle it safely. An application using
	  capabilty-URIs SHOULD redact them internally as soon as possible if it doesn't prevent the
	  application from working correctly. When there is a safety trade-off on an application
	  keeping capability-URIs vs. redacting them internally, an application SHOULD present users
	  a choice.
	</t>
	<t>
	  The use of <xref target="attenuation">attenuation</xref> and of <xref
	  target="revocation">revocable</xref> capabilities with short lifetimes constitutes a
	  second line of defence against leaks.
	</t>
	<t>
	  As with other credentials, in a web service exposing capability-URIs, their sensitive
	  components like the bearer token SHOULD NOT be stored unprotected. For example, as with
	  passwords, tokens can be stored hashed, which enables the service to find the authority
	  associated with an incoming request containing a valid token, but if the stored hashes get
	  leaked, they cannot be used as-is to make authenticated requests (and if they have been
	  properly generated, a brute-force attack has to search through a bigger and more uniform
	  space than with passwords).
	</t>

	<section title="Redacted URI scheme">
	  <t>
	    When an application redacts a capability-URI, to prevent any consumer of the redacted
	    URI to confuse it with a valid URI, an application MAY use the <tt>redacted:</tt> URI
	    scheme. The syntax of the redacted URI is simple: after the scheme goes the redacted URI
	    reference, unescaped, but with any part deemed sensitive substituted.
	  </t>
	  <t>
	    It is RECOMMENDED to substitute each sensitive portion of the original URI with the
	    percent-encoded control character "substitute" (<tt>%1A</tt>), as it is highly unlikely
	    to appear in any unredacted URI. An application SHOULD NOT substitute a sensitive
	    portion with the same number of substitution characters as the length of the sensitive
	    portion, but rather with a single reckognizable character or character sequence.
	  </t>
	  <t>
	    An application displaying a redacted URI SHOULD display a substitution character or
	    character sequence as a block wider than a character.
	  </t>
	  <t>
	    The syntax of redacted URIs and IRIs is the following:
	  </t>
	  <t><figure><artwork>
redacted-uri   = "redacted:" URI-reference
redacted-iri   = "redacted:" IRI-reference

URI-reference  = &lt;URI-reference, see [RFC3986], Section 4.1>
IRI-reference  = &lt;IRI-reference, see [RFC3987], Section 2.2>
	  </artwork></figure></t>
	  <t>
	    Examples:
	  </t>
	  <table>
	    <thead><tr><th>Redacted URI</th><th>Possible display</th></tr></thead>
	    <tbody>
	      <tr>
		<td><tt>redacted:cap-https:%1A@foo.io/quux/1234</tt></td>
		<td><tt>cap-https:████@foo.io/quux/1234</tt></td>
	      </tr>
	      <tr>
		<td><tt>redacted:cap-https:bt=%1A;*tf=bisc@bar.net/?search=%1A</tt></td>
		<td><tt>cap-https:bt=████;*tf=bisc@bar.net/?search=████</tt></td>
	      </tr>
	      <tr>
		<td><tt>redacted:cap-https:%1A@baz.com/%1A</tt></td>
		<td><tt>cap-https:████@baz.com/████</tt></td>
	      </tr>
	      <tr>
		<td><tt>redacted:data:,John %1A, born %1A</tt></td>
		<td><tt>John ████, born ████</tt></td>
	      </tr>
	    </tbody>
	  </table>
	  <t>
	    Note that by using <tt>data:</tt> URIs, application can use the <tt>redacted:</tt> URI
	    scheme to mark non-URI data as redacted.
	  </t>
	  <t>
	    An application providing multiple ways to redact capability-URIs SHOULD provide a
	    default operation where the whole <tt>authoritzation</tt> component is redacted. When
	    implementing the handling of capability-URIs with respect to an existing API to handle
	    generic URIs, this default operation SHOULD be how capability-URIs are rendered as
	    strings or in serialization, to ensure that code that isn't specifically designed to
	    handle capability-URIs doesn't leak sensitive information:
	  </t>
	  <t><figure><artwork>
> foo = parse_URI("cap-https://bt=zk3fv2E5KsjyYdT9I0rzPg@example.com/foo/bar?baz=quux")
> foo.to_string()
"redacted:cap-https://%1A@example.com/foo/bar?baz=quux"

> {target: foo}.to_json()
'{"target":"redacted:cap-https://%1A@example.com/foo/bar?baz=quux"}'
          </artwork></figure></t>
	  <t>
	    Beware that this breaks the expectation that string parsing/rendering or
	    serialization/deserialization are couples of inverse operations.
	  </t>
	</section>
      </section>

      <section anchor="notls" title="Using bearer tokens without TLS">
	<t>
	  <xref target="RFC6750"/> mandates the use of <xref target="RFC9846">TLS</xref> because
	  transmitting bearer tokens on an unprotected channel is deemed too risky in the use case
	  of OAuth. But fine grained capabilities have a wider use case than OAuth and may be used
	  between services where security is guaranteed at a different layer, like <xref
	  target="RFC6071">IPsec</xref> or when services are communicating on a dedicated virtual
	  network (which is typical in some cloud deployments). For this reason, this specification
	  describes the use of bearer tokens both with and without TLS.
	</t>
	<t>
	  Of course, <tt>cap-http</tt> and <tt>cap-ws</tt> URIs SHOULD NOT, in general, be used over
	  an unprotected channel. Doing so would make it possible for an observer anywhere on the
	  path between the client and the server to store and reuse any capability that isn't
	  otherwise limited in its use (including the capability in the request and any capabilities
	  in the response).
	</t>
	<t>
	  There are a few scenarios where using capability-URIs on an unprotected channel would be
	  safe, though. Sending a request to a single-use capability-URI where the server's response
	  isn't private (and especially doesn't contain other capability-URIs) would give an
	  observer almost no surface attack (it would reveal one of the server's routes as well as
	  the shape of some of the tokens used).
	</t>
      </section>

      <section anchor="unforgeable" title="Capabilities must be unforgeable">
	<t>
	  For capabilities to enforce their security model, an attacker must not be able to create a
	  capability not explicitly given to them.
	</t>
	<t>
	  In an Object-Capability system (as first formalized in <xref target="robust"
	  format="title"/>), capabilities cannot be created from arbitrary data, they are not a
	  secret sequence of bits. But capability-URIs are just secret sequences of characters, so
	  their safety resides in being unguessable by an attacker.
	</t>
	<t>
	  While this specification doesn't impose any constraint on the nature of the bearer tokens
	  used (beyond being encoded to only use the available characters for their part of the
	  URI), any application creating capability-URIs MUST apply the currently known techniques
	  to generate tokens that are sufficiently difficult to guess, according to the threat model
	  considered.
	</t>
	<t>
	  Among the known techniques typically used to make tokens unguessable, they can be:
	</t>
	<list style="symbols">
	  <t>
	    A number generated within a wide enough range by a cryptographically secure PRNG,
	    sometimes called a Swiss number (in reference to Swiss numbered bank accounts). A Swiss
	    number is usually encoded in base32 or base64. (see <xref target="oob"/> for the use of
	    different encodings)
	  </t>
	  <t>
	    The permissions as data, protected with cryptography: encrypted such that only the
	    destination service can encrypt and decrypt it, and/or signed. <xref target="biscuit"
	    format="none">Biscuit</xref> is a recent example of the latter, and it is capable of
	    <xref target="offatt">offline attenuation</xref>.
	  </t>
	</list>
	<section anchor="confinement" title="The limits on confinement">
	  <t>
	    Because capability-URIs are secret sequences of characters, they can be transformed and
	    sliced in such ways that their nature cannot be recognized reliably. For that reason,
	    most access abstractions that limit the transmission of capability-URIs can be defeated
	    if an agent on one side of the abstraction is cooperating with an agent on the other
	    side in order to leak authority.
	  </t>
	  <t>
	    The ability to guarantee that an agent doesn't have authority to observe or create side
	    effects is called confinement. It is possible within an Object-Capability system even
	    between mutually untrusting agents, but not with capability-URIs.
	  </t>
	  <t>
	    For example, even if agent Mallet is running inside a <xref
	    target="membrane">membrane</xref>, agent Ned has a capability-URI to Mallet wrapped by
	    the membrane, and there is no other channel between them, when Ned invokes the
	    capability-URI, agent Mallet can respond with an encrypted capability-URI and the secret
	    key needed to decrypt it. No membrane can expect to detect every way that this scenario
	    could play out and trying to detect many of them might be too expensive in terms of
	    computation and latency.
	  </t>
	  <t>
	    Still, to protect services that always give authority through full capability-URIs, a
	    membrane remains a reliable tool to provide safety and flexibility. Such services SHOULD
	    only use capability-URIs with their scheme, and SHOULD NOT rely on relative references,
	    except when the media type is unambiguous about which part of the response should be
	    resolved as a URI (like <xref target="html-living" format="none">HTML</xref> or <xref
	    target="jsonld" format="none">JSON-LD</xref>). This implies following <xref
	    target="rest" format="none">REST</xref>, instead of having clients construct URIs from
	    out-of-band logic and pieces of data.
	  </t>
	</section>
      </section>

      <section anchor="pola" title="POLA">
	<t>
	  The Principle of Least Authority says that every part of a system should only get the
	  least amount of authority needed to operate correctly, and no amount more. While widely
	  recommended, POLA is rarely put in practice, because in identity-based security
	  frameworks, POLA sits somewhere between impossible and impractical. But with capabilities,
	  POLA can become trivial to follow.
	</t>
	<t>
	  The basic design principles to adhere to POLA are the following:
	  <list style="numbers">
	    <t>
	      Every part of the system starts with no authority that can create or observe
	      side-effects (basically, only read immutable files), except:
	      <list style="symbols">
		<t>
		  the authority needed to be invoked by its callers, which includes receiving data
		  and capabilities and replying with data and capabilities
		</t>
		<t>
		  its "own" authority, that it exposes (e.g. the permissions to read and write to
		  some part of a filesystem for a storage service); that authority is doled out to
		  its callers with the process of <xref target="attenuation">attenuation</xref>.
		</t>
	      </list>
	    </t>
	    <t>
	      Any authority needed to process an invocation by a caller should come from
	      capabilities contained in the invocation.
	    </t>
	  </list>
	  <t>
	    Mainstream operating systems make it harder to enforce POLA at the process level. By
	    default, any process can read and write mutable files, listen on network ports and
	    initiate network connections. Still, sandboxing and containerization tools make it
	    possible to remove those ambient authorities.
	  </t>
	  <t>
	    But at the web service level, authority often comes from authenticated HTTP requests,
	    which makes it easier to start a service with no authority, by giving it no credentials
	    in its configuration. Again, the exception to that rule would be its "own" authority,
	    like some service exposing a cache that has the credentials to connect to a database in
	    its configuration. <xref target="bootstrap"/> shows how this works in practice in a full
	    scenario starting with the first deployment of a web service.
	  </t>
	</t>
      </section>

      <section anchor="revocation" title="Revocation">
	<t>
	  If a web service just lets you create capabilities and send them out, they would be
	  irrevocable delegations of your authority. The corresponding issue with ACLs is that you
	  can't have an ACL about the ACL, or you would need an ACL about the ACL about the ACL, and
	  so on…
	</t>

	<section title="Caretaker">
	  <t>
	    Fortunately, with capabilities, we have several solutions that don't have this issue of
	    infinite recursion. The simplest is the pattern named the "caretaker". If <tt>Alice</tt>
	    wants to share with <tt>Bob</tt> a revocable access to <tt>Carol</tt>, <tt>Alice</tt>
	    can create a proxy object <tt>CarolCaretaker</tt> giving it their capability to
	    <tt>Carol</tt>. A caretaker has two facets, each with a separate capability: a proxy
	    facet that just forwards invocation to the capability given to it, and a revocation
	    facet that, when invoked, removes from its internal data the capability.
	  </t>
	  <t>
	    The architecture of the caretaker is an interesting illustration of POLA, more
	    specifically of one of its deeper design principles and one of its benefits. The deeper
	    design principle is to avoid having code make a policy decision when that decision could
	    be wrong. Better have the graph of authority support the desired policy by
	    construction. The caretaker doesn't decide that it should act as a proxy or not. When
	    revoked, it cannot act as a proxy anymore. The benefit is that a revoked caretaker
	    cannot be abused, confused or hacked later to exploit the authority initially given to
	    it: it doesn't hold that authority anymore.
	  </t>
	  <t>
	    In the case of the caretaker, this design principle emerges necessarily from POLA: when
	    the caretaker should stop working, it doesn't need the authority anymore. So it
	    shouldn't keep it. The trick is to look for other cases where a decision could be
	    transformed into a dynamic graph of capabilities that embodies the policy behind the
	    decision. For a concrete method to achieve this kind of design, the invariant that the
	    code shouldn't receive or keep excess authority is a kind a invariant that perfectly
	    lends itself to Edsger Dijkstra's method of "correct by construction".
	  </t>
	  <t>
	    <xref target="weather"/> shows an example of creating, sending, using and revoking a
	    caretaker.
	  </t>
	</section>

	<section anchor="membrane" title="Membrane">
	  <t>
	    When the response from requesting a capability-URI may contain further capabilities, a
	    simple caretaker isn't sufficient to safely revoke authority. With just a caretaker, the
	    initial capability would stop being proxied, but the user of the caretaker could
	    continue to use any authority received through the caretaker as capabilities (which
	    would not be proxied).
	  </t>
	  <t>
	    In such a case, a safer and slightly more complex solution is the membrane (described in
	    <xref target="robust" format="title"/>, figure 9.3, and in <xref target="proxies"
	    format="title"/>, section 5). When a membrane sees a capability-URI in the response, it
	    substitutes it with a capability-URI to a caretaker. When the membrane is revoked, all
	    the caretakers it created are revoked as well (but see <xref target="confinement">the
	    limits on confinement</xref>).
	  </t>
	</section>

	<section title="Certificate revocation">
	  <t>
	    When using certificate chains as capabilities (see <xref target="offatt">offline
	    attenuation</xref>), they usually provide an automatic membrane: certificates each can
	    have an identifier and the service can keep a list of revoked certificates. Any
	    capability delegated from a revoked capability is also revoked. This is how <xref
	    target="biscuit-revocation" format="none">revocation of Biscuits</xref> works.
	  </t>
	</section>
      </section>

      <section anchor="attenuation" title="Attenuation">
	<t>
	  Capability attenuation is a process that takes a capability as input and produces a new
	  capabiliy as output, whose authority is a subset of the input capability's authority.
	</t>
	<t>
	  The use of attenuation is another design principle that emerges necessarily from
	  POLA. Most agents start with one or several capabilities with a broad authority. When they
	  delegate authority to other agents or services to act on their behalf, it almost always
	  needs to be vastly narrower, so attenuated capabilities are used.
	</t>
	<t>
	  For example, let's say Alice has a capability with read/write authority to her whole
	  online file storage, and a capability to a photo annotation service. She obviously doesn't
	  want that service to be able to read her private files, about her finances, her health, or
	  her diaries. She doesn't want to lose her valuable photo collection to a bug in the
	  service or a data ransom attack, so she doesn't trust the service with read/write access
	  to the photos.
	</t>
	<t>
	  Alice would then create two attenuated capabilities to her file storage, one with
	  read-only authority over <tt>/Photos/Family</tt>, where the subset or her photo collection
	  is that she wants annotated, and one with read/write authority over
	  <tt>/Photos/Famly_annotations</tt>, an empty folder where the service can write the
	  metadata it produces.
	</t>

	<section title="Attenuation by default">
	  <t>
	    When a service exposes authority through capability-URIs, like a file storage or a
	    business dashboard, it SHOULD by default expose each element through an attenuated
	    capability. For example, using bearer tokens, requesting a directory listing from a file
	    storage SHOULD result in a list with each file in the directory with a corresponding
	    capability-URI whose token can only be used to access that file. If that file is itself
	    a directory, listing its contents SHOULD also work the same way. When accessed with
	    read-write authority, such a storage service MAY either include two capabilities for
	    each file in a listing, one for read/write authority, the other for read-only authority,
	    or MAY provide a way to get a read-only version of any read/write capability. Of course,
	    in almost all cases, listing a directory through a capability-URI with read-only
	    authority SHOULD only produce other capabilities with read-only authority (there are
	    very few exceptions that would make sense with respect to security).
	  </t>
	  <t>
	    This way of getting attenuated capabilities has the benefit that it usually matches the
	    users' intention and intuition. Even if I navigate through my business dashboard and
	    share with someone the direct, irrevocable capability-URI to something, it would not be
	    different than if, in a physical office, I gave someone the key to a storage room,
	    telling them to do some task in there, like shredding all files older than 10 years.
	  </t>
	  <t>
	    Of course, most services that expose such a graph of attenuated capability-URIs SHOULD
	    include features to wrap them in a membrane to enable <xref
	    target="revocation">revocation</xref>.
	  </t>
	</section>

	<section title="Attenuation by intermediary">
	  <t>
	    A service may provide access abstractions (like the caretaker) that aren't expressive
	    enough to implement your desired policies. For example, a file storage service may
	    provide a tree of attenuated read/write and read-only capabilities, and the ability to
	    wrap any of them in a membrane, but this is not expressive enough to implement the
	    following policies:
	  </t>
	  <list style="symbols">
	    <t>
	      The authority to read a specific file, only once
	    </t>
	    <t>
	      The authority to append to a specific file, but not to read or modify the existing
	      contents
	    </t>
	    <t>
	      The authority to create a new writable file, but not to read of modify any existing
	      file in the same directory
	    </t>
	    <t>
	      The authority to walk only once through a tree of directories, read only one file,
	      only once
	    </t>
	  </list>
	  <t>
	    One solution is to expose another service, that provides the missing access
	    abstrations. In some cases, like the single-use restriction, such a service can be
	    trivially composed with others without knowledge about their API. Such a wrapper needs
	    only to know the target capability-URI and will, only once, forward any request and
	    forward the response back.
	  </t>
	  <t>
	    Many variants of the single-use wrapper can be designed, including the simplest which
	    forwards the response untouched, one that enforces a truly single-use authority by
	    stripping all capability-URIs from the response, or one where the single-use restriction
	    only applies to the initial capability, but all capabilities in the initial response get
	    wrapped in a membrane for future revocation (but see <xref target="confinement">the
	    limits on confinement</xref> for they are limits on those last two). One of the common
	    use cases for capabilty-URIs that are single-use while giving access to less restricted
	    capability-URIs is when the single-use capability-URI is sent through an unprotected
	    channel (like email), or to ensure forward secrecy.
	  </t>
	  <t>
	    In contrast, the three other policies in the example above would need knowledge of the
	    storage API to be able to implement the access abstraction.
	  </t>
	  <t>
	    A service providing access abstractions is a way to expose capability-URIs that give
	    access to a legacy service that isn't capability-based itself.
	  </t>
	</section>

	<section anchor="offatt" title="Offline attenation">
	  <t>
	    Several capability systems use a cryptographical chain of certificates as a capability,
	    designed in such a way that when an agent has a chain <tt>[C0,C1,C2]</tt>, it cannot
	    extract the chain <tt>[C0,C1]</tt> and use it. Either it can extract it and cannot use
	    it (e.g. because <tt>C1</tt> designates a public key whose private key is needed to use
	    the capability, which is the case with <xref target="zcap" format="none">zcaps</xref>
	    and <xref target="ucan" format="none">UCANs</xref>), or it cannot extract it
	    (e.g. because the chains actually look like <tt>[C0,C1,K1]</tt> and
	    <tt>[C0,C1,C2,K2]</tt> and so the agent receiving the second capability misses
	    <tt>K1</tt> to reconstruct the full parent capability, which is the case with <xref
	    target="biscuit" format="none">biscuits</xref>).
	  </t>
	  <t>
	    When such a system is used to create capability-URIs, then an agent holding a
	    capability-URI can create attenuated capability-URIs without contacting any web
	    service. To advertise this possibility, capability-URIs can use the <xref
	    target="token-format"><tt>tf</tt> parameter</xref>.
	  </t>
	  <t>
	    Offline attenuation has several benefits. It makes it possible to use some new access
	    abstractions with limited or no change in the web service's code. It means that the web
	    service doesn't need to store capabilities itself, and the proliferation of attenuated
	    capabilities doesn't create a burden on the web service. It also removes the web service
	    as a point of failure: when the holder of a capability is offline or even when the web
	    service itself is unavailable, capabilities can still be attenuated and communicated
	    between agents for later use with the web service. The cost is the size of the tokens.
	  </t>
	</section>
      </section>

      <section title="Responsibility tracking">
	<t>
	  As much as capabilities make it easier and safer to design systems that better prevent
	  unwanted accesses and are more robust in the face of negligent or malicious behavior, they
	  also make it possible to track complex chains of responsibility in cases where unwanted
	  accesses happen.
	</t>
	<t>
	  The difference with ACL security is important. In an ACL system, permissions are usually
	  granted broadly and often in advance. For example, all members of a lab might get added to
	  a group that has write access to the files of all active projects of the lab, or maybe to
	  groups linked to projects they participate in if security is tighter. If Mallet want some
	  file overwritten without logs pointing to them, they set things up so that Bob will
	  instruct Alice to write data in the targeted file. When it is later discovered that it
	  wasn't the right file for what she wrote and she overwrote and lost valuable information,
	  in the system itself, we may have only limited evidence:
	  <list style="symbols">
	    <t>when user X put Alice in the relevant group</t>
	    <t>when user Y gave that group write permissions on the file</t>
	    <t>when Alice modified the file</t>
	  </list>
	  Users X and Y probably did their changes long before the unwanted access happened and none
	  of them is Bob or Mallet. Depending on the system, on top of Alice being indirectly duped
	  to write to some path, another person might have been indirectly duped so that this
	  unassumng file path is actually a link to something else. The paths could have been
	  communicated with all kinds of services, or even given by speech or written by hand, so
	  they may not be anywhere in the security logs. Ultimately, Mallet might not have himself
	  the authority in the system to write the file, nor Bob. In this scenario, even if
	  permissions are given narrowly, they would not show any evidence against Mallet.
	</t>
	<t>
	  In a capability system, people cannot be duped to enter a path as the target of a link or
	  write operation when those require a capability, not a path. This means that Mallet needs
	  to have access to the targeted file himself. When Alice writes the file, the system can be
	  designed to log that it's with a capability given by Bob, itself using a capability given
	  by Mallet.
	</t>

	<section title="Responsability tracking protocols">
	  <t>
	    Capabilities in general and REST share two features: being layered systems and having a
	    uniform interface. Those make it possible to implement intermediate layers adding a
	    feature to the overall system that are independent of the service behind
	    them. Revocation (see <xref target="revocation"/>) may be the simmplest. A
	    responsibility tracking protocol is another.
	  </t>
	  <t>
	    TODO
	  </t>
	</section>
      </section>

      <section anchor="y-property" title="Y-Property">
	<t>
	  If Alice has a capability to Bob and Carol, and Alice sends a message to Bob with the
	  capability to Carol, the exchange has the Y-property if Alice's message to Bob is
	  sufficient for Bob to establish a protected channel with Carol.
	</t>
	<t>
	  Simple <tt>https</tt> URIs don't support the Y-property for two reasons:
	  <list style="symbols">
	    <t>
	      Bob also need to know in advance the certificate authority used by the target server.
	    </t>
	    <t>
	      If an attacker can have Bob contact a malicious server with a certificate using a
	      certificate authority known to Bob, Bob will establish a channel with the attacker,
	      not Carol.
	    </t>
	  </list>
	</t>
	<t>
	  Using the <tt>y-cert-param</tt> component, the client doesn't need to know a shared
	  certificate authority in advance, and it can verify during TLS handshake that it is
	  establishing a connection with the intended server.
	</t>
	<t>
	  Even if an attacker manages to alter the DNS records of the name used for the server,
	  making it possible to have a valid certificate from a widely known certificate authority,
	  the client would be able to detect that the server is not the one that Alice intended.
	</t>
	<t>
	  This also enables a safe use of self-signed certificates, for more self-sufficient
	  systems.
	</t>
      </section>

      <section anchor="oob" title="Out-of-band communication">
	<t>
	  Transcription is an important design goal of URIs (see <xref target="RFC3986"/>, section
	  1.2.2). Capability-URIs are designed to retain that ability, hence having the embedded URI
	  or IRI unchanged (and not needing to percent-encode any part of it).
	</t>
	<t>
	  Capability-URIs and web-caps can be designed to facilitate two out-of-band communications:
	  written transcription and dictation, but there is a trade-off between this facilitation
	  and safety.
	</t>
	<t>
	  When the authorization data is a bearer token, it can be encoded as a series of words like
	  an <xref target="xkcd" format="none">XCKD password</xref>. Some algorithms of this kind
	  use a word list optimized for memorization of the phrase, or designed so that no two
	  entries of the word list are likely to be mixed when reading, writing or saying them out
	  loud, making manual transcription or dictation of a capability-URI both easy and reliable
	  (other examples include the PGP word list or <xref target="RFC1751"/>).
	</t>
	<t>
	  Some word lists are localized, like in <xref target="bip39" format="none">BIP39</xref>,
	  and those can be used in capability-URIs that are IRIs.
	</t>
	<t>
	  Other algorithms don't use a word list but encode sequences of bits as syllables, usually
	  with an emphasis on ensuring unambiguous pronounciation (examples include <xref
	  target="proquints" format="none">proquints</xref> and <xref target="singsong"
	  format="none">Sing-song</xref>).
	</t>
	<t>
	  The trade-off comes from the fact that manually writing or saying aloud a very long list
	  of words or syllables can be daunting and error-prone. When generating and encoding a
	  Swiss number (see <xref target="unforgeable"/>), an application MAY choose to reduce the
	  size, making the resulting token easier to write and say, but also more vulnerable to
	  several attacks. Such capability-URIs or web-caps SHOULD have an appropriately short time
	  of use and/or be usable only once.
	</t>
      </section>

      <section title="Protection against CSRF">
	<t>
	  The use of capability-URIS according to <xref target="pola">POLA</xref> is resistant to
	  CSRF attacks because an attacker cannot forge a request that the targeted user is
	  authorized to make but the attacker isn't. By definition, when you combine authority with
	  designation, noone can request what they are not authorized to do.
	</t>
	<t>
	  Of course, like any security framework, the design of an application can go against its
	  principles and be unsafe despite the framework. If a service A holds a capabiliy-URI to
	  service B with a broad authority, where part of the embedded URI is a guessable resource
	  name, and service A uses resource names from its client requests, then service A has
	  succesfully circumvented POLA and made itself vulnerable to confused deputy attacks,
	  despite the use of capabilities.
	</t>
	<t>
	  An example of such a bad design would be (using URI templates, see <xref
	  target="RFC6570"/>):
	  <list style="symbols">
	    <t>
	      Service B is accessed by Service A through
	      <tt>cap-https://K_qCxe8msbJGU4kkIIbSpA@quux.org/serviceB{?resource}</tt>
	    </t>
	    <t>
	      Service A is accessed by its clients through
	      <tt>https://quux.org/serviceA{?resource}</tt>
	    </t>
	  </list>
	</t>
      </section>

      <section title="Protection against XSS">
	<t>
	  Most previous uses of bearer tokens that protect against CSRF are vulnerable to XSS
	  because some tokens with broad authority are stored in a global mutable store where
	  XSS-injected malicious code can trivially read them (like the <tt>localStorage</tt> of a
	  Web browser).
	</t>
	<t>
	  But with the combined use of REST and capability-URIs, client-side code can use
	  capability-URIs in such a way that they are never stored except in the local variables of
	  the functions using them, where XSS-injected malicious code cannot read them without the
	  support of attacks like Meltdown or Spectre.
	</t>
	<t>
	  When using capability-URIs in a browser's address bar, either with a browser capable of
	  using capability-URI directly, or with web-caps, a Web application SHOULD redact the
	  address bar as soon as possible, as XSS-injected malicious code can trivially read it.
	</t>
      </section>
    </section>

    <section title="IANA Considerations">
      <t>
	This specification defines several new URI schemes. Here are the informations for
	their registration to IANA according to <xref target="BCP35"/>.
      </t>
      <section title="cap-http">
	<list style="hanging">
	  <t hangText="Scheme name"><tt>cap-http</tt></t>
	  <t hangText="Status">Provisional</t>
	  <t hangText="Applications/protocols that use this scheme name">TBD</t>
	</list>
      </section>
      <section title="cap-https">
	<list style="hanging">
	  <t hangText="Scheme name"><tt>cap-https</tt></t>
	  <t hangText="Status">Provisional</t>
	  <t hangText="Applications/protocols that use this scheme name">TBD</t>
	</list>
      </section>
      <section title="cap-ws">
	<list style="hanging">
	  <t hangText="Scheme name"><tt>cap-ws</tt></t>
	  <t hangText="Status">Provisional</t>
	  <t hangText="Applications/protocols that use this scheme name">TBD</t>
	</list>
      </section>
      <section title="cap-wss">
	<list style="hanging">
	  <t hangText="Scheme name"><tt>cap-wss</tt></t>
	  <t hangText="Status">Provisional</t>
	  <t hangText="Applications/protocols that use this scheme name">TBD</t>
	</list>
      </section>
      <section title="redacted">
	<list style="hanging">
	  <t hangText="Scheme name"><tt>redacted</tt></t>
	  <t hangText="Status">Provisional</t>
	  <t hangText="Applications/protocols that use this scheme name">TBD</t>
	</list>
      </section>
    </section>

    <section anchor="ack" title="Acknowledgements">
      <t>
	The idea of a capability-URI was independently discovered by several people before this
	specification was imagined and written, and its final form draws a lot of elements from the
	work of Tyler Close (<xref target="yurl" format="title"/>, <xref target="web-key"
	format="title"/>), Neil Madden (<xref target="neilmadden" format="title"/>), Ariadne Conill
	(<xref target="ariadneconill" format="title"/>) and Christine Lemmer-Webber.
      </t>
      <t>
	The <tt>bearcap</tt> URI scheme was broader in that it was supposed to embed any URI where a
	bearer token might be used to create a capability URI. Using dedicated URI schemes to embed
	HTTP URIs has several desirable properties:</t>
	<list style="symbol">
	  <t>
	    First and foremost, it avoids the confusion when new URIs are embedded in
	    capability-URIs. Different implementations might presume different semantics or
	    implementation details which, for something that is central to security, can easily lead
	    to serious security issues. Thus, if another URI scheme can be embedded as a
	    capability-URI, a new scheme will be created with precise semantics.
	  </t>
	  <t>
	    When embedding a URI with query parameters and/or a fragment, it avoids the need to
	    escape them, which makes such URIs easier to transcribe, which is an important design
	    goal of URIs (see <xref target="oob">out-of-band communication</xref>).
	  </t>
	  <t>
	    When using absolute capability-URIs, the sensitive information is in a part of the URI
	    that the generic syntax of URIs already treats as sensitive, which makes it more likely
	    that even software that doesn't recognizes these new URI schemes would handle the
	    sensitive part accordingly (but an application SHOULD NOT rely on that, see <xref
	    target="credentials"/>).
	  </t>
	</list>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml-rfcsubseries/reference.BCP.14.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml-rfcsubseries/reference.BCP.35.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3279.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3987.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4648.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6234.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6455.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6750.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8246.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9111.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9112.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9113.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9114.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9846.xml"/>
    </references>

    <references title="Informative references">
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1751.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6071.xml"/>
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6570.xml"/>
      
      <reference anchor="aclsdont"
		 target="https://papers.agoric.com/papers/acls-dont/abstract/">
	<front>
	  <title>ACLs Don't</title>
	  <author fullname="Tyler Close"/>
	</front>
      </reference>

      <reference anchor="robust"
		 target="https://papers.agoric.com/papers/robust-composition/abstract/">
	<front>
	  <title>Robust Composition: Towards a Unified Approach to Access Control and Concurrency
	  Control</title>
	  <author fullname="Mark S. Miller"/>
	</front>
      </reference>
      
      <reference anchor="capmyths"
		 target="https://papers.agoric.com/papers/capability-myths-demolished/abstract/">
	<front>
	  <title>Capability Myths Demolished</title>
	  <author fullname="Mark S. Miller"/>
	  <author fullname="Ka-Ping Yee"/>
	  <author fullname="Jonathan Shapiro"/>
	</front>
      </reference>
      
      <reference anchor="proxies"
		 target="https://dl.acm.org/doi/10.1145/1899661.1869638">
	<front>
	  <title>Proxies: design principles for robust object-oriented intercession APIs</title>
	  <author fullname="Tom Van Cutsem"/>
	  <author fullname="Mark S. Miller"/>
	</front>
      </reference>
      
      <reference anchor="neilmadden"
		 target="https://neilmadden.blog/2021/03/20/towards-a-standard-for-bearer-token-urls/">
	<front>
	  <title>Towards a standard for bearer token URLs</title>
	  <author fullname="Neil Madden"/>
	</front>
      </reference>
      
      <reference anchor="ariadneconill"
		 target="https://ariadne.space/2019/10/10/demystifying-bearer-capability-uris.html">
	<front>
	  <title>Demystifying Bearer Capability URIs</title>
	  <author fullname="Ariadne Conill"/>
	</front>
      </reference>

      <reference anchor="xkcd"
		 target="https://xkcd.com/936/">
	<front>
	  <title>Password Strength</title>
	  <author fullname="Randall Munroe"/>
	</front>
      </reference>
      
      <reference anchor="yurl"
		 target="https://web.archive.org/web/20040221205825/http://www.waterken.com/dev/YURL/httpsy/">
	<front>
	  <title>Waterken™ YURL</title>
	  <author fullname="Tyler Close"/>
	</front>
      </reference>
      
      <reference anchor="web-key"
		 target="https://waterken.sourceforge.net/web-key/">
	<front>
	  <title>Mashing with permission</title>
	  <author fullname="Tyler Close"/>
	</front>
      </reference>
      
      <reference anchor="webarch"
		 target="https://www.w3.org/TR/webarch/">
	<front>
	  <title>Architecture of the World Wide Web, Volume One</title>
	  <author fullname="Tim Berners-Lee"/>
	  <author fullname="Tim Bray"/>
	  <author fullname="Dan Connolly"/>
	  <author fullname="Paul Cotton"/>
	  <author fullname="Roy Fielding"/>
	  <author fullname="Mario Jeckle"/>
	  <author fullname="Chris Lilley"/>
	  <author fullname="Noah Mendelsohn"/>
	  <author fullname="David Orchard"/>
	  <author fullname="Norman Walsh"/>
	  <author fullname="Stuart Williams"/>
	</front>
      </reference>

      <reference anchor="rest"
		 target="https://roy.gbiv.com/pubs/dissertation/top.htm">
	<front>
	  <title>Architectural Styles and the Design of Network-based Software Architectures</title>
	  <author fullname="Roy Fielding"/>
	</front>
      </reference>

      <reference anchor="biscuit"
		 target="https://www.biscuitsec.org/">
	<front>
	  <title>Eclipse Biscuit</title>
	  <author fullname="Geoffroy Couprie"/>
	  <author fullname="Clément Delafargue"/>
	  <author fullname="Cédric Corbière"/>
	</front>
      </reference>

      <reference anchor="biscuit-revocation"
		 target="https://www.biscuitsec.org/docs/guides/revocation/">
	<front>
	  <title>Biscuit — Revocation</title>
	  <author fullname="Geoffroy Couprie"/>
	  <author fullname="Clément Delafargue"/>
	  <author fullname="Cédric Corbière"/>
	</front>
      </reference>

      <reference anchor="zcap"
		 target="https://w3c-ccg.github.io/zcap-spec/">
	<front>
	  <title>Authorization Capabilities for Linked Data</title>
	  <author fullname="Christine Lemmer-Webber"/>
	  <author fullname="Manu Sporny"/>
	  <author fullname="Mark S. Miller"/>
	</front>
      </reference>

      <reference anchor="ucan"
		 target="https://github.com/ucan-wg/spec/">
	<front>
	  <title>User Controlled Authorization Network (UCAN) Specification</title>
	  <author fullname="Irakli Gozalishvili"/>
	  <author fullname="Daniel Holmgren"/>
	  <author fullname="Philipp Krüger"/>
	  <author fullname="Brooklyn Zelenka"/>
	</front>
      </reference>

      <reference anchor="csp"
		 target="https://w3c.github.io/webappsec-csp/">
	<front>
	  <title>Content Security Policy Level 3</title>
	  <author fullname="Mike West"/>
	  <author fullname="Antonio Sartori"/>
	</front>
      </reference>

      <reference anchor="html-living"
		 target="https://html.spec.whatwg.org/">
	<front>
	  <title>HTML Living Standard</title>
	  <author/>
	</front>
      </reference>

      <reference anchor="jsonld"
		 target="https://www.w3.org/TR/json-ld/">
	<front>
	  <title>JSON-LD 1.1<br/>A JSON-based Serialization for Linked Data</title>
	  <author fullname="Manu Sporny"/>
	  <author fullname="Dave Longley"/>
	  <author fullname="Gregg Kellogg"/>
	  <author fullname="Markus Lanthaler"/>
	  <author fullname="Pierre-Antoine Champin"/>
	  <author fullname="Niklas Lindström"/>
	</front>
      </reference>

      <reference anchor="bip39"
		 target="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">
	<front>
	  <title>Mnemonic code for generating deterministic keys</title>
	  <author fullname="Marek Palatinus"/>
	  <author fullname="Pavol Rusnak"/>
	  <author fullname="Aaron Voisine"/>
	  <author fullname="Sean Bowe"/>
	</front>
      </reference>

      <reference anchor="proquints"
		 target="https://arxiv.org/abs/0901.4016v2">
	<front>
	  <title>A Proposal for Proquints: Identifiers that are Readable, Spellable, and
	  Pronounceable</title>
	  <author fullname="Daniel Shawcross Wilkerson"/>
	</front>
      </reference>

      <reference anchor="singsong"
		 target="https://blog.vrypan.net/2026/08/19/260819-sing-song/">
	<front>
	  <title>Sing-song: a speakable encoding for long numbers and keys</title>
	  <author fullname="Panagiotis Vryonis"/>
	</front>
      </reference>

    </references>

    <section anchor="bootstrap" title="Bootstrapping a web service with POLA">
      <t>
	When a service exposes authority, it might be counter-intuitive that every invocation of the
	service should still provide the authority needed for the service to respond. This example
	shows how this could work with a file storage service.
      </t>
      <t>
	The service is first deployed with only permissions to:
	<list style="symbols">
	  <t>
	    read its configuration file, which contains one root capability that has read/write
	    authority on the service's storage
	  </t>
	  <t>
	    read and write to one folder, <tt>/srv/storage</tt>
	  </t>
	  <t>
	    listen to incoming HTTP requests
	  </t>
	</list>
      </t>
      <t>
	The service's administrator will use the root capability to create folders, named according
	to usernames allocated to users. Creating a folder <tt>alice</tt> with the root capability
	would have the service create a folder <tt>/srv/storage/alice</tt>. This means that the
	administrator doesn't need special tools to create folders that are private to users. Its
	power doesn't come from special operations, only from where the root capability gives
	authority to read and write.
      </t>
      <t>
	The user Alice would receive the capability-URI to use her own storage space, unaware if,
	under the hood, her files are in <tt>/srv/storage/alice</tt>, <tt>/srv/storage/user1</tt> or
	any other path. Through her capability-URI, no parent directory and no full path is
	visible. When she in turn wants to create a folder <tt>projects</tt>, and later a folder
	<tt>projects/report</tt>, she would not use a path like <tt>alice/projects/report</tt>. She
	would use her initial capability to create a folder <tt>projects</tt>. This would in turn
	give her a capability to that folder, and she would use that capability to create a folder
	<tt>report</tt>.
      </t>
      <t>
	This means that the storage service doesn't need to decide if a user has the right to access
	something. It is inherent to the capability that they can. In its internal database, the
	service maintains a mapping between capabilities, operations and paths. If it finds a path
	associated with the capability and the operation, it operates in that path. Using
	capabilities to interact with the service although it obviously has the authority to act on
	the underlying storage is what makes the whole thing actually secure: the service cannot be
	confused to use its own authority to do operations that the user isn't authorized to do. And
	an attacker cannot construct a request to have a user with more authorization send it to the
	service.
      </t>
      <t>
	This also means that the root capability isn't special. It will just be associated on
	startup with the root of the space. This means that full administrative rights can be
	delegated in folders just by giving a read/write capability-URI for that folder. A user
	without access to the configuration file, given a capability-URI and instructed to be the
	administrator, wouldn't know if they are administering the full storage space or a subspace.
      </t>
      <t>
	If it is desirable that some administrators cannot access the users' private folders, one
	additional attenuation available from a folder with read/write access would be to make it so
	the only operation is to create new folders in it but the resulting read/write
	capability-URI is sent to an inbox given as a parameter, verifiable through the storage
	service for the recipient. The service could even be configured so that the root capability
	is that kind of capability, and no level of administrator can read everyone's files.
      </t>
    </section>

    <section anchor="weather" title="Weather service caretaker">
      <t>
	Here's an example of creating, sending, using and revoking a caretaker. The APIs seen in
	this example are hypothetical, not part of this specification. The APIs use a JSON-like data
	model and the pseudo-code may or may not be valid in some existing programming language, and
	omits the boilerplate that may be needed to ensure encoding and decoding of native data
	structures to a format that supports that data model, like JSON or CBOR.
      </t>
      <t>
	Let's say user Alice has three capability-URIs, to Bob's inbox, to a service to create
	caretakers that she trusts, and to a high-resolution weather service she's paying for:
	<list style="symbols">
	  <t><tt>cap-https://bt=ZseIJun3ksCGGpIelt53zg@bob.net/inbox</tt></t>
	  <t><tt>cap-https://bt=x5bFnods8Dq_pKhfDP-1Dw@alice.io/new-caretaker</tt></t>
	  <t><tt>cap-https://bt=oKFejFiwgz-JDYbh2OOR7g@high-res-weather.io/report</tt></t>
	</list>
      </t>
      <t>
	Alice makes the following request to create the caretaker:
      </t>
      <t><figure><artwork>
http.post("cap-https://bt=x5bFnods8Dq_pKhfDP-1Dw@alice.io/new-caretaker",
         {target: "cap-https://bt=oKFejFiwgz-JDYbh2OOR7g@high-res-weather.io/report"})
      </artwork></figure></t>
      <t>
	The response from the server is:
      </t>
      <t><figure><artwork>
{invoke: "cap-https://bt=i1NLl48cmHZllBHmdA70UQ@alice.io/caretaker",
 revoke: "cap-https://bt=VgOO0MrxbcAHHLp3_nH_GQ@alice.io/caretaker"}
      </artwork></figure></t>
      <t>
	Then Alice sends both of the received capabilities to Bob's inbox:
      </t>
      <t><figure><artwork>
http.post("cap-https://bt=ZseIJun3ksCGGpIelt53zg@bob.net/inbox",
          {message: "Here's the high-res weather API, I'll let you use it during your
                     week at sea. You can revoke your access yourself when you're
                     back on land."
           attachments:
            [{label: "invoke":,
              type: "cap",
              content: "cap-https://bt=i1NLl48cmHZllBHmdA70UQ@alice.io/caretaker"},
             {label: "revoke",
              type: "cap",
              content: "cap-https://bt=VgOO0MrxbcAHHLp3_nH_GQ@alice.io/caretaker"}]})
      </artwork></figure></t>
      <t>
	Alice can feel safe that she didn't give Bob any dangerous authority. He can only use the
	caretaker and render it useless. If Bob forgets to do so, or tries to extend his use of
	the caretaker, at any point, Alice can use the <tt>revoke</tt> capability so that the
	caretaker loses its internal capability.
      </t>
      <t>
	The caretaker is simple enough that it makes composition with other tools trivial. For
	example, Alice could set up a timed worker, e.g. as a cron job, to invoke the
	<tt>revoke</tt> capability after some time. Again, that worker wouldn't need a complex and
	possibly dangerous authority to do its job. It wouldn't need the authority to make arbitrary
	network connections or even arbitrary HTTP requests. In terms of both authority, persistent
	state and code complexity, it would not need to deal with any multi-step authentication
	process, and the storage of cookies and temporary tokens. It would only need access to time
	(and not even that when the worker is a cron job), the ability to make a request for a
	capability-URI, and the <tt>revoke</tt> capability-URI.
      </t>
    </section>
    
    <section anchor="web-key-desc" title="Web-keys">
      <t>
	The Waterken project figured that if you're forced to use legacy <tt>https</tt> URIs as
	capabilities in the browser, one major and very problematic source of leakage would be the
	<tt>Referer</tt> header, because clicking such a link to a different server could leak the
	URI containing the token.
      </t>
      <t>
	The solution used in web-keys was to put the token in the fragment, because HTTP/1.1
	precludes the fragment being in the <tt>Referer</tt> header (and browsers were seen to
	respect the RFC on that point, see <xref target="RFC9110"/>, section 10.1.3).
      </t>
      <t>
	Because the fragment is not sent to the server, the mechanism of the web-key is for the
	representation of the resource to be a Web page with client-side code that will read the
	token in the fragment and make a second request, replacing the content of the page with the
	response to the second request.
      </t>
      <t>
	The intermediary Web page is a very simple piece of code, and can have a reasonably long
	cache expiration, which means that after the first request for a web-key on one server,
	every following request for a web-key is a single request.
      </t>
    </section>

  </back>
</rfc>

