This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git
The following commit(s) were added to refs/heads/main by this push:
new 98118be Document the proposed ATR API security model
98118be is described below
commit 98118be98ad88da7aab13fa5f633a32a7fc44b4f
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Jul 7 19:15:02 2025 +0100
Document the proposed ATR API security model
---
docs/api-security.html | 22 ++++++++++++++++++++++
docs/api-security.md | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/docs/api-security.html b/docs/api-security.html
new file mode 100644
index 0000000..f8f694e
--- /dev/null
+++ b/docs/api-security.html
@@ -0,0 +1,22 @@
+<h1>ATR API security model</h1>
+<p>All ATR routes, on both the website and the API, require HTTPS using TLS
1.2 or newer for their transport.</p>
+<p>There are two access levels to the ATR API: public and committer. Public
API endpoints are accessible to everybody. Committer endpoints have the
following accessibility criteria instead.</p>
+<h2>PATs</h2>
+<p>Committers must obtain a <a
href="https://en.wikipedia.org/wiki/Personal_access_token">Personal Access
Token</a> (PAT) from the ATR website at the route <code>/tokens</code>. Only
committers, signed in through <a href="https://oauth.apache.org/api.html">ASF
OAuth</a> to ATR, can obtain PATs. Each PAT expires in 180 days, and can be
revoked at any time by the user at the same route. ATR does not store PATs,
only the hashes of PATs.</p>
+<h2>JWTs</h2>
+<p>To make a request to a committer protected endpoint on the API, committers
must first obtain a <a
href="https://en.wikipedia.org/wiki/JSON_Web_Token">JWT</a>. They can do this
in one of two ways:</p>
+<ol>
+<li>For debugging, obtaining a JWT from the <code>/tokens</code> page.</li>
+<li>For script use, obtaining a JWT by POSTing their PAT in a JSON payload to
the API endpoint <code>/api/jwt</code>. This is a public route, and requires a
payload such as <code>{"asfuid": "${ASF_UID}",
"pat": "${PAT_TOKEN}"}</code>. The response will be
<code>{"asfuid": "${ASF_UID}", "jwt":
"${JWT_TOKEN}"}</code>.</li>
+</ol>
+<p>Every JWT issued by the ATR expires in 90 minutes, uses the HS256
(HMAC-SHA256) algorithm, and makes <code>sub</code> (ASF UID), <code>iat</code>
(issue time), <code>exp</code> (expires at), and <code>jti</code> (token
payload) claims. JWTs are stateless, so there is no analogue stored by the ATR,
except for the secret symmetric key of the server which is initialised on
startup. If the ATR server is restarted, all JWTs are expired immediately.</p>
+<p>The JWT can be used to access protected endpoints by using it in the
<code>Authorization</code> header as a bearer token, i.e. <code>Authorization:
Bearer ${JWT_TOKEN}</code>. PATs and JWTs must never appear in URLs. They must
be protected by the user at all times. Accidental sharing of a PAT or a JWT
must be reported to ASF security.</p>
+<p>Note that PATs cannot be used to access protected endpoints. They can only
be used to issue a JWT, which is then used to access protected endpoints.</p>
+<p>Endpoints which mutate state, require significant computation, or have
large or sensitive payloads use POST. All other endpoints use GET.</p>
+<h2>Limitations</h2>
+<p>We do not currently support scopes in either PATs or JWTs, but are
considering this.</p>
+<p>Admins are able to revoke any PAT, and users are able to revoke any of
their own PATs, but neither admins nor users are able to revoke JWTs on an
individual basis. Restarting the server resets the server secret symmetric key,
which has the side effect of expiring all JWTs, and can be used in an
emergency.</p>
+<p>We do not have refresh tokens, and do not plan to implement refresh tokens.
PATs must be used to issue a new JWT through the API.</p>
+<p>We do not presently have logging or auditing of the logging for the API.
Once we implement logging, we must ensure that tokens and other sensitive data
are not stored.</p>
+<p>We do not use all available JWT fields, such as <code>iss</code>
(issuer).</p>
+<p>We do not rate limit PAT or JWT issuance.</p>
diff --git a/docs/api-security.md b/docs/api-security.md
new file mode 100644
index 0000000..b9fffc8
--- /dev/null
+++ b/docs/api-security.md
@@ -0,0 +1,39 @@
+# ATR API security model
+
+All ATR routes, on both the website and the API, require HTTPS using TLS 1.2
or newer for their transport.
+
+There are two access levels to the ATR API: public and committer. Public API
endpoints are accessible to everybody. Committer endpoints have the following
accessibility criteria instead.
+
+## PATs
+
+Committers must obtain a [Personal Access
Token](https://en.wikipedia.org/wiki/Personal_access_token) (PAT) from the ATR
website at the route `/tokens`. Only committers, signed in through [ASF
OAuth](https://oauth.apache.org/api.html) to ATR, can obtain PATs. Each PAT
expires in 180 days, and can be revoked at any time by the user at the same
route. ATR does not store PATs, only the hashes of PATs.
+
+## JWTs
+
+To make a request to a committer protected endpoint on the API, committers
must first obtain a [JWT](https://en.wikipedia.org/wiki/JSON_Web_Token). They
can do this in one of two ways:
+
+1. For debugging, obtaining a JWT from the `/tokens` page.
+2. For script use, obtaining a JWT by POSTing their PAT in a JSON payload to
the API endpoint `/api/jwt`. This is a public route, and requires a payload
such as `{"asfuid": "${ASF_UID}", "pat": "${PAT_TOKEN}"}`. The response will be
`{"asfuid": "${ASF_UID}", "jwt": "${JWT_TOKEN}"}`.
+
+Every JWT issued by the ATR expires in 90 minutes, uses the HS256
(HMAC-SHA256) algorithm, and makes `sub` (ASF UID), `iat` (issue time), `exp`
(expires at), and `jti` (token payload) claims. JWTs are stateless, so there is
no analogue stored by the ATR, except for the secret symmetric key of the
server which is initialised on startup. If the ATR server is restarted, all
JWTs are expired immediately.
+
+
+The JWT can be used to access protected endpoints by using it in the
`Authorization` header as a bearer token, i.e. `Authorization: Bearer
${JWT_TOKEN}`. PATs and JWTs must never appear in URLs. They must be protected
by the user at all times. Accidental sharing of a PAT or a JWT must be reported
to ASF security.
+
+Note that PATs cannot be used to access protected endpoints. They can only be
used to issue a JWT, which is then used to access protected endpoints.
+
+Endpoints which mutate state, require significant computation, or have large
or sensitive payloads use POST. All other endpoints use GET.
+
+## Limitations
+
+We do not currently support scopes in either PATs or JWTs, but are considering
this.
+
+Admins are able to revoke any PAT, and users are able to revoke any of their
own PATs, but neither admins nor users are able to revoke JWTs on an individual
basis. Restarting the server resets the server secret symmetric key, which has
the side effect of expiring all JWTs, and can be used in an emergency.
+
+We do not have refresh tokens, and do not plan to implement refresh tokens.
PATs must be used to issue a new JWT through the API.
+
+We do not presently have logging or auditing of the logging for the API. Once
we implement logging, we must ensure that tokens and other sensitive data are
not stored.
+
+We do not use all available JWT fields, such as `iss` (issuer).
+
+We do not rate limit PAT or JWT issuance.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]