asf-tooling commented on issue #926:
URL:
https://github.com/apache/tooling-trusted-releases/issues/926#issuecomment-4410001615
<!-- gofannon-issue-triage-bot v2 -->
**Automated triage** — analyzed at `main@2da7807a`
**Type:** `discussion` • **Classification:** `no_action` •
**Confidence:** `high`
**Application domain(s):** `release_lifecycle`,
`authentication_authorization`, `artifact_upload`
### Summary
This issue is an ongoing coordination discussion between ATR maintainers and
the Maven ATR plugin developers (@hboutemy, @slawekjaranowski) about how the
plugin should use ATR's API. The original issue proposed a 4-step workflow (get
JWT, check release exists, create release, upload files). @sbp identified the
rate-limiting concern (JWT created per file vs reused). The discussion has
since evolved into plugin governance (Maven vs Tooling namespace), repository
location, and release process decisions. No concrete changes to the ATR
codebase have been requested or identified as necessary — the work is primarily
in the external maven-studies repository.
### Where this lives in the code today
#### `atr/post/tokens.py` — `jwt_post` (lines 37-50)
_currently does this_
The JWT issuance endpoint rate-limited to 10/hour, which @sbp flagged as a
concern when the plugin was creating a JWT per file upload.
```python
@post.typed
@rate_limiter.rate_limit(10, datetime.timedelta(hours=1))
async def jwt_post(
session: web.Committer, _tokens_jwt: Literal["tokens/jwt"], form:
shared.tokens.IssueForm
) -> web.QuartResponse:
"""
URL: /tokens/jwt
"""
async with storage.write(session) as write:
wafc = write.as_foundation_committer()
jwt_token = await wafc.tokens.issue_jwt(form.pat)
response = web.TextResponse(jwt_token)
response.headers["Cache-Control"] = "no-store"
return response
```
#### `atr/jwtoken.py` — `issue` (lines 71-89)
_currently does this_
JWT has a 30-minute TTL (via _ATR_JWT_TTL = 30 * 60), meaning one JWT can be
reused across multiple file uploads within that window.
```python
def issue(uid: str, *, ttl: int = _ATR_JWT_TTL, pat_hash: str | None = None)
-> str:
# audit_guidance no explicit typ header or token_type claim is added:
the aud claim (_ATR_JWT_AUDIENCE)
# already acts as an explicit token type discriminator, and ATR issues
only one JWT type verified
# by a single internal verifier — the RFC 9068 typ header is relevant to
multi-issuer OAuth2 RS
# deployments, which this is not
now = datetime.datetime.now(tz=datetime.UTC)
payload = {
"sub": uid,
"iss": _ATR_JWT_ISSUER,
"aud": _ATR_JWT_AUDIENCE,
"iat": now,
"nbf": now,
"exp": now + datetime.timedelta(seconds=ttl),
"jti": secrets.token_hex(128 // 8),
}
if pat_hash:
payload["atr_th"] = pat_hash
log.auth_event("jwt_issuance", uid, pat_hash=pat_hash if pat_hash else
None)
return jwt.encode(payload, _signing_key(), algorithm=_ALGORITHM)
```
#### `atr/post/upload.py` — `_add_files` (lines 55-70)
_currently does this_
The upload endpoint that the Maven plugin calls to upload files. It supports
JSON responses (content negotiation), which is what the Maven plugin uses.
```python
async def _add_files(
session: web.Committer,
add_form: shared.upload.AddFilesForm,
project_key: safe.ProjectKey,
version_key: safe.VersionKey,
*,
wants_json: bool,
) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse:
try:
file_data = add_form.file_data
async with storage.write(session) as write:
wacp = await write.as_project_committee_participant(project_key)
creation_error, number_of_files, was_quarantined = await
wacp.release.upload_files(
project_key, version_key, file_data
)
```
#### `atr/storage/writers/release.py` — `CommitteeParticipant.start` (lines
609-616)
_currently does this_
The release creation logic that step 3 of the proposed workflow would
invoke. It checks for existing releases (returning 409 if one exists) and
validates committee membership.
```python
async def start(self, project_key: safe.ProjectKey, version:
safe.VersionKey) -> tuple[sql.Release, sql.Project]: # noqa: C901
"""Creates the initial release draft record and revision
directory."""
# Get the project from the project name
project = await self.__data.project(
key=str(project_key), status=sql.ProjectStatus.ACTIVE,
_committee=True
).get()
if not project:
raise storage.AccessError(f"Project {project_key} not found",
status=404)
```
### Proposed approach
No code changes to this repository are required at this time. The issue is a
coordination discussion about the Maven ATR plugin (maintained externally at
https://github.com/apache/maven-studies/blob/maven-atr-plugin/). The plugin is
actively being developed and tested by @hboutemy and @slawekjaranowski. The
remaining open items are governance decisions (repository location, groupId,
release process) rather than ATR codebase changes. The rate-limiting concern
raised by @sbp has been acknowledged by @hboutemy as a plugin-side fix (reuse
JWT rather than creating one per file). The ATR API endpoints needed by the
plugin (JWT issuance, release creation, file upload) all exist and function
correctly based on the successful tests shown in the discussion.
### Open questions
- Whether any ATR API changes are needed to support the 'check if release
exists' step (the issue mentions /release/get which may or may not be an
existing API route - the file inventory doesn't include the full API layer)
- Whether the 'POST data for create' changes mentioned in the issue body
have already been made or are still pending
- Whether the rate limit of 10 JWT requests/hour is sufficient for the Maven
plugin workflow or needs adjustment
- Whether the plugin will live under apache/tooling-atr-maven-plugin or
remain in Maven namespace - this is still being debated as of the latest
comments
_The agent reviewed this issue and is not proposing patches in this run.
Review the existing-code citations and open questions above before deciding
next steps._
### Files examined
- `atr/jwtoken.py`
- `atr/storage/writers/tokens.py`
- `atr/post/tokens.py`
- `atr/storage/writers/release.py`
- `atr/post/upload.py`
- `atr/storage/readers/releases.py`
- `atr/storage/writers/revision.py`
- `atr/get/tokens.py`
---
*Draft from a triage agent. A human reviewer should validate before merging
any change. The agent did not run tests or verify diffs apply.*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]