72 Commits

Author SHA1 Message Date
Latte aefb243a05 Merge pull request 'Feat/raw api dispatch' (#58) from feat/raw-api-dispatch into dev
docker / test (push) Successful in 27s
test / test (push) Successful in 35s
docker / lint (push) Successful in 33s
lint / lint (push) Successful in 35s
docker / docker (push) Successful in 42s
Reviewed-on: #58
2026-06-26 10:33:10 +00:00
Latte 7f7aaab5a6 test(raw-api): cover gitea_request handler and path parsing
docker / lint (push) Successful in 38s
docker / test (push) Successful in 33s
docker / test (pull_request) Successful in 32s
test / test (push) Successful in 40s
lint / lint (push) Successful in 42s
docker / lint (pull_request) Successful in 39s
test / test (pull_request) Successful in 39s
lint / lint (pull_request) Successful in 40s
docker / docker (pull_request) Successful in 31s
docker / docker (push) Successful in 44s
Covers read allow + repository parsing, write denied without write-mode, write
allowed only for whitelisted repos, non-repo write denial, sensitive-path
denial (incl. GET) and override, cross-repo search handling, unknown-method and
traversal rejection before any network call, killswitch, response truncation,
and the raw path-parsing helpers and raw-aware extractors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 12:26:57 +02:00
Latte 8c84d76bd5 docs(raw-api): document gitea_request, env vars and policy examples
Adds docs/raw-api.md (two-layer policy, sensitive denylist, env vars, write-mode
warning), links it from index and api-reference, documents RAW_API_ENABLED /
RAW_API_ALLOW_SENSITIVE in .env.example, and adds commented virtual-tool-name
deny examples to policy.yaml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 12:26:57 +02:00
Latte 8e41fd12af feat(raw-api): register gitea_request tool and wire server dispatch
Registers gitea_request in AVAILABLE_TOOLS with write_operation=False
(deliberate: a static flag cannot describe a read-or-write tool; the handler
authorizes writes per-method) and maps the tool name to raw_api_request_tool in
the server handler registry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 12:26:56 +02:00
Latte 2844c42ec8 feat(raw-api): add gitea_request schema, path parsing, client dispatch and handler
Adds the RawApiRequestArgs schema (extra=forbid), raw path normalization/
parsing helpers, a GiteaClient.raw_request that audits method+path only (never
the body), and the raw_api_request_tool handler. The handler derives a coarse
virtual tool name (gitea_request:METHOD:topsegment) plus repository/target_path
from the path and runs them back through the policy engine, enforces an
admin/credential sensitive-path denylist, and bounds responses. Two config
flags gate it: RAW_API_ENABLED (killswitch) and RAW_API_ALLOW_SENSITIVE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 12:26:26 +02:00
Latte 227122263b Merge pull request 'Fix/get issue 27 error handling and ci' (#28) from fix/get-issue-27-error-handling-and-ci into dev
docker / test (pull_request) Successful in 32s
test / test (pull_request) Successful in 40s
docker / lint (pull_request) Successful in 40s
lint / lint (pull_request) Successful in 42s
docker / test (push) Successful in 29s
docker / lint (push) Successful in 35s
lint / lint (push) Successful in 36s
test / test (push) Successful in 35s
docker / docker (push) Successful in 45s
docker / docker (pull_request) Successful in 49s
Reviewed-on: #28
2026-06-25 14:56:04 +00:00
Latte 4fb315b177 commit
docker / test (push) Successful in 29s
docker / lint (push) Successful in 37s
lint / lint (push) Successful in 41s
test / test (push) Successful in 42s
docker / test (pull_request) Successful in 32s
docker / lint (pull_request) Successful in 41s
lint / lint (pull_request) Successful in 39s
test / test (pull_request) Successful in 37s
docker / docker (push) Successful in 48s
docker / docker (pull_request) Successful in 45s
2026-06-25 16:53:41 +02:00
Latte 41749fd7b4 fix: harden get_issue parsing and surface real errors (#27); align CI image publish
get_issue raised 'NoneType' object is not iterable on issues whose
labels/assignees Gitea returns as null or with non-dict elements (the #13
class), which reached clients as an opaque JSON-RPC -32603 with no detail.

- read_tools: skip non-dict label/assignee entries in get_issue_tool
- server: detect a wrapped GiteaNotFoundError via the __cause__ chain and
  return 404 / JSON-RPC -32000 with a clear message; include the exception
  type name in masked internal errors so future masked failures are
  diagnosable without exposing messages or stack traces
- tests: cover non-dict collection elements and the not-found / typed-error
  responses
- ci: rewrite docker.yml to build, smoke-test and push the image to the
  Gitea container registry on merge to main/dev, matching the hiddenden.cafe
  pattern (only REGISTRY_TOKEN required)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 16:51:58 +02:00
Latte 026f3a654f Merge pull request 'feat: assign issues to milestones on create/update (#22)' (#25) from feat/issue-milestone-assignment into main
docker / test (push) Successful in 29s
docker / lint (push) Successful in 35s
lint / lint (push) Successful in 36s
test / test (push) Successful in 35s
docker / docker-test (push) Successful in 7s
docker / docker-publish (push) Successful in 5s
Reviewed-on: #25
2026-06-22 16:00:29 +00:00
Latte e08ba42697 feat: assign issues to milestones on create/update (#22)
docker / test (pull_request) Successful in 29s
docker / lint (pull_request) Successful in 35s
lint / lint (pull_request) Successful in 35s
test / test (pull_request) Successful in 35s
docker / docker-test (pull_request) Successful in 8s
docker / docker-publish (pull_request) Has been skipped
test / test (push) Successful in 23s
lint / lint (push) Successful in 23s
Add a `milestone` argument to `create_issue` and `update_issue` accepting
either a numeric milestone id or a title (resolved case-insensitively against
open and closed milestones, with a clear error for unknown titles). On
`update_issue`, `milestone: 0` clears the milestone. A BeforeValidator rejects
booleans so they are not silently coerced to an id.

Gitea Projects (Kanban boards) were investigated for #22 and are intentionally
left unsupported: Gitea 1.26.2 exposes no project endpoints in its REST API.
Documented this in api-reference.md and refreshed the (stale) write-mode tool
list to cover all 16 write tools.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 17:36:01 +02:00
Latte 10a307ac02 Merge pull request 'feat: structured logging helpers + get_issue instrumentation (#14)' (#24) from feat/get-issue-debug-logging into dev
docker / test (pull_request) Successful in 27s
docker / lint (pull_request) Successful in 34s
lint / lint (pull_request) Successful in 36s
docker / docker-test (pull_request) Successful in 7s
test / test (pull_request) Successful in 35s
docker / docker-publish (pull_request) Has been skipped
lint / lint (push) Successful in 36s
docker / test (push) Successful in 28s
docker / lint (push) Successful in 35s
test / test (push) Successful in 36s
docker / docker-test (push) Successful in 11s
docker / docker-publish (push) Successful in 5s
Reviewed-on: #24
2026-06-22 15:09:58 +00:00
Latte 538d6d964a test: cover write-tool auth and backend error branches
lint / lint (push) Successful in 36s
docker / test (pull_request) Successful in 32s
test / test (push) Successful in 38s
docker / lint (pull_request) Successful in 38s
docker / docker-test (pull_request) Successful in 12s
docker / docker-publish (pull_request) Has been skipped
test / test (pull_request) Successful in 25s
lint / lint (pull_request) Successful in 27s
Every write tool's `except (Auth...)` re-raise and `except GiteaError ->
RuntimeError` wrapping was previously untested, leaving write_tools at 60%
coverage and the repo below the 80% gate. Adds parametrized error-path tests
for all 15 write tools (backend error wrapping + auth propagation), raising
write_tools coverage to 99% and total coverage above the gate.
2026-06-22 15:58:59 +02:00
Latte f53e1a3a5a feat: add structured logging helpers and instrument get_issue (#14)
docker / test (pull_request) Successful in 29s
test / test (push) Successful in 38s
lint / lint (push) Successful in 39s
docker / lint (pull_request) Successful in 39s
docker / docker-test (pull_request) Successful in 12s
docker / docker-publish (pull_request) Has been skipped
lint / lint (pull_request) Successful in 28s
test / test (pull_request) Successful in 22s
Adds reusable, secret-safe logging helpers to `logging_utils`:
- `log_event(logger, level, event, **context)` emits a named event with a
  sanitized `context` mapping (sensitive keys masked as `***`).
- `log_nullable_field(...)` records whether a parsed field is None plus its
  runtime type, without dumping its contents.
- `sanitize_context(...)` is the shared masking primitive.

The JSON formatter now serializes a record's `context` into the payload.

`get_issue_tool` is instrumented at DEBUG (`get_issue.start`,
`get_issue.payload_shape`, `get_issue.field_check` for labels/assignees/user)
so the nullable-field parsing that caused #13 is diagnosable going forward.

Adds tests for the helpers, the formatter, and the get_issue instrumentation,
and documents the pattern in docs/observability.md.
2026-06-22 15:40:36 +02:00
Latte cd309ee290 Merge pull request 'fix: tolerate null labels/assignees/user in get_issue (#13)' (#23) from fix/get-issue-none-iterable into dev
docker / test (push) Successful in 29s
docker / lint (push) Successful in 36s
test / test (push) Successful in 36s
lint / lint (push) Successful in 36s
docker / docker-test (push) Successful in 7s
docker / docker-publish (push) Successful in 5s
Reviewed-on: #23
2026-06-22 12:50:08 +00:00
Latte 478aee9bed fix: tolerate null labels/assignees/user in get_issue (#13)
test / test (push) Successful in 25s
lint / lint (push) Successful in 27s
docker / test (pull_request) Successful in 32s
docker / lint (pull_request) Successful in 39s
lint / lint (pull_request) Successful in 34s
test / test (pull_request) Successful in 32s
docker / docker-test (pull_request) Successful in 11s
docker / docker-publish (pull_request) Has been skipped
Gitea may return JSON null for an issue's `labels`, `assignees`, or
`user` fields. `dict.get(key, [])` returns None when the key is present
with a null value (the default is only used for missing keys), so the
list comprehensions raised `'NoneType' object is not iterable` for
otherwise-valid issues. Coalesce with `or []` / `or {}` so empty/null
collections normalize to empty results.

Adds a regression test covering all three null fields.
2026-06-22 10:43:43 +02:00
Latte 5f80fc2531 Merge pull request 'Feat/expand gitea toolset' (#20) from feat/expand-gitea-toolset into main
docker / test (push) Successful in 33s
docker / lint (push) Successful in 41s
docker / docker-publish (push) Successful in 6s
lint / lint (push) Successful in 39s
test / test (push) Successful in 38s
docker / docker-test (push) Successful in 36s
Reviewed-on: #20
2026-06-14 18:48:36 +00:00
Latte b62ed098bf feat: add 13 read tools (PR files/commits, comments, branches, releases, milestones, org/status/languages/topics)
test / test (push) Successful in 1m13s
lint / lint (push) Successful in 1m14s
docker / docker-publish (pull_request) Has been skipped
docker / test (pull_request) Successful in 22s
docker / lint (pull_request) Successful in 29s
lint / lint (pull_request) Successful in 31s
test / test (pull_request) Successful in 21s
docker / docker-test (pull_request) Successful in 23s
Expands the read surface so the MCP can inspect more of Gitea:

- list_pull_request_files, list_pull_request_commits, list_issue_comments
- list_branches, get_branch
- get_release, get_latest_release, list_milestones
- get_commit_status
- list_org_repositories, list_organizations
- get_repo_languages, list_repo_topics

Each: arg schema (extra=forbid; GitRef on branch/sha fields), Gitea client
method with url-encoded path segments, bounded handler, MCP registration
(read-only), server wiring, docs, and parametrized success tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:43:03 +02:00
Latte 7837ff43ad feat: add PR/release/branch/milestone/comment write tools
Adds six opt-in write tools (write-mode + policy + per-user permission still
enforced; no destructive or admin actions):

- create_pull_request (POST /pulls)
- create_release / edit_release (POST/PATCH /releases)
- create_branch (POST /branches; create only, no deletion)
- create_milestone (POST /milestones)
- edit_issue_comment (PATCH /issues/comments/{id})

Each: arg schema (extra=forbid, GitRef on branch/ref-like fields), Gitea client
method with url-encoded path segments, handler that surfaces auth errors, MCP
registration (write_operation=True), server wiring, docs, and success tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:38:25 +02:00
Latte c282ffe359 feat: complete label management (name->id resolution, update/remove)
Resolves the long-standing problem that label tools passed names while Gitea's
API requires numeric label ids.

- gitea_client: add _resolve_label_ids() helper; create_issue and add_labels now
  resolve label names to ids (case-insensitive) and raise a clear "Unknown
  label(s)" error instead of a generic 500.
- New tools: remove_labels (by name) and update_label (located by current name).
- Register both write tools and document the name-based label contract.
- Tests: resolver mapping + unknown-label error, add_labels id translation,
  update_label and remove_labels handlers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:34:35 +02:00
Latte f0db219ee8 feat: add create_label write tool
Adds a create_label write-mode tool so labels can be created in a repository
through the MCP server (previously there was no way to define labels, which
blocked attaching labels to issues). Follows the full tool checklist:

- arguments.py: CreateLabelArgs (name, hex color, optional description/exclusive),
  with extra=forbid and a hex-color pattern.
- gitea_client.py: create_label() POSTing to /repos/{owner}/{repo}/labels with
  url-encoded path segments.
- write_tools.py: create_label_tool handler; normalizes the color to a leading
  '#', bounds text output, and lets auth/authz errors surface.
- mcp_protocol.py: register create_label (write_operation=True).
- server.py: wire create_label into TOOL_HANDLERS.
- docs/api-reference.md: document create_label.
- tests: success path, color normalization, and invalid-color rejection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:24:33 +02:00
Latte e873d0325b feat: scope list_repositories to the authenticated user in service-PAT mode
docker / test (push) Successful in 28s
docker / lint (push) Successful in 33s
test / test (push) Successful in 33s
lint / lint (push) Successful in 35s
docker / docker-test (push) Successful in 10s
docker / docker-publish (push) Successful in 6s
Previously list_repositories was blocked in service-PAT mode because it has no
repository target for the per-user permission check, so users could not list
their repositories at all (the connector surfaced a generic error).

list_repositories now returns only the repositories the signed-in user owns or
contributes to, instead of everything the bot token can see:
- gitea_client.py: add list_user_repositories(login) — resolves the user id and
  queries /api/v1/repos/search with the uid filter.
- repository.py: list_repositories_tool uses the user-scoped path when a service
  PAT is configured and a user login is present; pure-OAuth mode still uses the
  user's own /user/repos.
- server.py: allow list_repositories through the service-PAT guard (it is scoped
  to the user in the handler); all other tools still require a repository target.
- README.md: document the new user-scoped behavior and its visibility caveat.

Tests: user-scoped client method (uid resolution + unknown user), PAT-mode tool
scoping, and conftest now clears the request context between tests to prevent
contextvar login leakage across files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 17:07:19 +02:00
Latte 624a3c79ee fix: surface Gitea auth errors and document the service PAT
docker / test (push) Successful in 25s
docker / lint (push) Successful in 30s
test / test (push) Successful in 32s
lint / lint (push) Successful in 33s
docker / docker-test (push) Successful in 10s
docker / docker-publish (push) Successful in 6s
Two related issues made the connected MCP server return a bare "Internal
server error" for tools that need real Gitea API access (e.g.
list_repositories), while public-repo-by-path reads worked:

1. Gitea OIDC access tokens only carry openid/profile/email and cannot call
   the repository REST API, so pure-OAuth mode fails for most tools. A service
   PAT (GITEA_TOKEN) is required in practice; per-user permission is still
   enforced before each call, so this does not weaken authorization.
2. The tool handlers caught GiteaError broadly and re-raised it as RuntimeError.
   Because GiteaAuthenticationError/GiteaAuthorizationError subclass GiteaError,
   a clean 401/403 was masked as a generic internal error and the server's
   re-authorization guidance never fired.

Changes:
- read_tools.py / repository.py / write_tools.py: re-raise the auth/authz
  subclasses before the broad GiteaError catch so server.py returns actionable
  guidance instead of a generic 500.
- .env.example + README.md: document GITEA_TOKEN as a least-privilege bot PAT,
  explain why it's needed and that OAuth remains authoritative, and note that
  list_repositories is intentionally unavailable in service-PAT mode.
- tests: assert tool handlers propagate auth errors unwrapped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:47:10 +02:00
Latte b1bc726a95 fix: keep OAuth flow working on read-only container roots
docker / test (push) Successful in 29s
docker / lint (push) Successful in 34s
test / test (push) Successful in 32s
lint / lint (push) Successful in 36s
docker / docker-test (push) Successful in 8s
docker / docker-publish (push) Successful in 6s
The DCR client registry created its storage directory eagerly in __init__,
and DCR_STORAGE_PATH defaulted to /var/lib/aegis-mcp — a path that is neither
created in the image nor mounted as a writable volume. Under the hardened
read-only docker-compose, every /oauth/authorize, /oauth/token, and /register
call hit `mkdir('/var/lib/aegis-mcp')` on a read-only filesystem, raising an
unhandled OSError and returning a bare "Internal Server Error" during login.

- oauth_flow.py: defer the storage-dir mkdir from __init__ to _persist (the
  only write path). authorize/token only read the registry, so they no longer
  require a writable filesystem and stop 500-ing.
- docker/Dockerfile: create and chown /var/lib/aegis-mcp.
- docker-compose.yml + docker/docker-compose.yml: add a persistent
  aegis-mcp-data volume mounted at /var/lib/aegis-mcp so DCR registrations
  survive restarts.
- .env.example: document DCR_STORAGE_PATH and set PUBLIC_BASE_URL to the real
  MCP host.
- README.md: spell out exact values (Gitea host, MCP host, callback URL, MCP
  URL) and add a "required writable volumes" section explaining the cause of
  the login 500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:28:52 +02:00
Latte 84bbff4acb Merge pull request 'fix: prevent path traversal via Gitea ref/sha/base/head parameters' (#18) from fix/gitea-ref-path-traversal into main
docker / test (push) Successful in 30s
docker / lint (push) Successful in 37s
test / test (push) Successful in 33s
docker / docker-test (push) Successful in 13s
lint / lint (push) Successful in 37s
docker / docker-publish (push) Successful in 6s
Reviewed-on: #18
2026-06-14 14:01:58 +00:00
Latte 2d95e89035 fix: prevent path traversal via Gitea ref/sha/base/head parameters
test / test (push) Successful in 20s
lint / lint (push) Successful in 22s
docker / lint (pull_request) Successful in 33s
docker / test (pull_request) Successful in 25s
test / test (pull_request) Successful in 38s
lint / lint (pull_request) Successful in 40s
docker / docker-test (pull_request) Successful in 15s
docker / docker-publish (pull_request) Has been skipped
The ref-like tool arguments (ref, sha, base, head) were only length-limited
and were interpolated unencoded into Gitea API URL paths (get_tree,
get_commit_diff, compare_refs). Because httpx collapses ".." path segments
(RFC 3986), a crafted value such as "../../../../owner/repo/contents/secret"
escaped the declared owner/repo prefix. In service-PAT mode this allowed a
user authorized on one repository to read arbitrary repositories the service
token could reach, and in OAuth mode it bypassed the policy engine's
per-repository rules (which never see ref values).

Two defense layers:
- arguments.py: add _validate_git_ref / GitRef that rejects ".." path
  segments, leading "/", backslashes, null bytes, control chars, whitespace,
  and "?"/"#", while preserving legitimate slash refs (feature/foo, v1.2.3).
  This is what actually closes the traversal.
- gitea_client.py: defense-in-depth urllib.parse.quote() on owner/repo
  (safe="") and ref/sha/base/head/filepath (safe="/") in every repo URL
  builder, mirroring the existing pattern in server.py.

Tests: negative cases for traversal/unsafe chars across all four fields,
positive cases for slash-containing refs, length-bound regression, and a
URL-layer confinement check. Full suite green (176 passed), coverage 85.64%.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 15:57:52 +02:00
Latte 90df37366f Merge pull request 'feat: harden OAuth state secret validation, DCR file permissions, and policy defaults' (#17) from feat/retarget-claude-mcp into main
docker / test (push) Successful in 27s
docker / lint (push) Successful in 34s
test / test (push) Successful in 32s
lint / lint (push) Successful in 34s
docker / docker-test (push) Successful in 6s
docker / docker-publish (push) Successful in 5s
Reviewed-on: #17
2026-06-14 12:17:37 +00:00
Latte 6be5ac3608 Merge branch 'main' into feat/retarget-claude-mcp
lint / lint (push) Successful in 39s
test / test (push) Successful in 37s
docker / lint (pull_request) Successful in 37s
docker / test (pull_request) Successful in 27s
docker / docker-test (pull_request) Successful in 11s
test / test (pull_request) Successful in 32s
lint / lint (pull_request) Successful in 34s
docker / docker-publish (pull_request) Has been skipped
2026-06-14 12:14:20 +00:00
Latte b8217dce8a feat: harden OAuth state secret validation, DCR file permissions, and policy defaults
docker / test (pull_request) Successful in 24s
lint / lint (pull_request) Successful in 37s
lint / lint (push) Successful in 1m26s
test / test (push) Successful in 1m40s
test / test (pull_request) Successful in 34s
docker / lint (pull_request) Successful in 1m59s
docker / docker-test (pull_request) Successful in 14s
docker / docker-publish (pull_request) Has been skipped
- Enforce 32-char minimum on OAUTH_STATE_SECRET at startup (config.py)
- Write DCR client registry with owner-only (0o600) permissions before atomic replace
- Flip policy.yaml default write action from allow → deny
- Add CLAUDE.md with architecture, commands, and AGENTS.md contract summary
- Add .pre-commit-config.yaml mirroring `make lint` checks
- Update .gitignore: add .venv, .claude, .mypy_cache, .ruff_cache, .coverage.*
- Extend docs: audit log rotation guidance, OAUTH_STATE_SECRET and DCR_STORAGE_PATH notes
- Tests: short-secret rejection, 32-char acceptance, POSIX permission check for DCR store

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 14:13:22 +02:00
Latte 6169a45193 Merge pull request 'Feat/retarget claude mcp' (#16) from feat/retarget-claude-mcp into main
docker / lint (push) Successful in 16s
docker / test (push) Successful in 13s
lint / lint (push) Successful in 16s
test / test (push) Successful in 14s
docker / docker-test (push) Successful in 31s
docker / docker-publish (push) Successful in 5s
Reviewed-on: #16
2026-06-13 19:38:46 +00:00
Latte b275f5c0c2 docs: retarget setup to Claude connectors
test / test (push) Has been cancelled
lint / lint (push) Has been cancelled
docker / test (pull_request) Successful in 13s
docker / lint (pull_request) Successful in 2m3s
lint / lint (pull_request) Successful in 16s
test / test (pull_request) Successful in 14s
docker / docker-test (pull_request) Successful in 42s
docker / docker-publish (pull_request) Has been skipped
2026-06-13 21:05:21 +02:00
Latte 541124e92a feat: harden Claude MCP OAuth transport 2026-06-13 21:05:11 +02:00
Latte ed3130ef74 refactor: lifespan handlers, module-level imports, bounded scope cache
Replace deprecated @app.on_event startup/shutdown handlers with a FastAPI
lifespan context manager, move the inline hashlib/time imports in the auth
middleware to module top, and back the unbounded _api_scope_cache with a new
size- and TTL-bounded BoundedTTLCache utility.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:39:06 +02:00
Latte 71c993e4cd Use GITEA_TOKEN as service PAT for API calls in OAuth mode
docker / lint (push) Failing after 21s
docker / test (push) Failing after 17s
lint / lint (push) Failing after 22s
test / test (push) Failing after 17s
docker / docker-test (push) Has been skipped
docker / docker-publish (push) Has been skipped
Gitea OIDC access_tokens only carry OIDC scopes and cannot call the
Gitea REST API. Fall back to GITEA_TOKEN (service PAT) for actual tool
execution when configured, while OIDC still handles user identity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 17:06:28 +00:00
Latte eada6d0f89 Merge pull request 'dev' (#12) from dev into main
docker / lint (push) Failing after 21s
docker / test (push) Failing after 16s
lint / lint (push) Failing after 21s
test / test (push) Failing after 1m12s
docker / docker-test (push) Has been skipped
docker / docker-publish (push) Has been skipped
Reviewed-on: #12
2026-03-04 16:55:31 +00:00
Latte 4e9422d6de Merge pull request 'fix' (#11) from fix into dev
docker / lint (push) Failing after 21s
lint / lint (pull_request) Failing after 22s
test / test (pull_request) Failing after 18s
docker / test (push) Failing after 16s
lint / lint (push) Failing after 22s
test / test (push) Failing after 18s
docker / lint (pull_request) Failing after 21s
docker / test (pull_request) Failing after 16s
docker / docker-test (push) Has been skipped
docker / docker-test (pull_request) Has been skipped
docker / docker-publish (push) Has been skipped
docker / docker-publish (pull_request) Has been skipped
Reviewed-on: #11
2026-03-04 16:55:18 +00:00
Latte bf35a0c712 Enhance OAuth metadata endpoints and update authorization server URLs in responses
lint / lint (push) Failing after 1m29s
test / test (push) Failing after 19s
docker / lint (pull_request) Failing after 21s
docker / test (pull_request) Failing after 16s
lint / lint (pull_request) Failing after 21s
test / test (pull_request) Failing after 18s
docker / docker-test (pull_request) Has been skipped
docker / docker-publish (pull_request) Has been skipped
2026-03-04 16:54:36 +00:00
Latte 0c61a6e0ab Merge pull request 'dev' (#10) from dev into main
docker / lint (push) Successful in 22s
docker / test (push) Successful in 17s
lint / lint (push) Successful in 23s
test / test (push) Successful in 19s
docker / docker-test (push) Successful in 7s
docker / docker-publish (push) Successful in 7s
Reviewed-on: #10
2026-02-27 20:09:00 +00:00
Latte cc86b28794 Merge pull request 'remove openrabbit' (#9) from update/image-build-workflow into dev
docker / docker-test (push) Successful in 7s
docker / docker-test (pull_request) Successful in 8s
docker / docker-publish (push) Successful in 7s
docker / docker-publish (pull_request) Has been skipped
docker / lint (push) Successful in 24s
docker / test (push) Successful in 18s
lint / lint (push) Successful in 24s
test / test (push) Successful in 19s
docker / lint (pull_request) Successful in 23s
lint / lint (pull_request) Successful in 24s
docker / test (pull_request) Successful in 19s
test / test (pull_request) Successful in 20s
Reviewed-on: #9
2026-02-27 20:08:45 +00:00
Latte 3bd09d02b2 remove openrabbit
lint / lint (push) Successful in 25s
test / test (push) Successful in 19s
docker / lint (pull_request) Successful in 23s
docker / test (pull_request) Successful in 18s
lint / lint (pull_request) Successful in 25s
test / test (pull_request) Successful in 19s
docker / docker-test (pull_request) Successful in 9s
docker / docker-publish (pull_request) Has been skipped
2026-02-27 21:08:15 +01:00
Latte f870d03e55 Merge pull request 'dev' (#8) from dev into main
docker / lint (push) Successful in 23s
docker / test (push) Successful in 18s
lint / lint (push) Successful in 22s
test / test (push) Successful in 19s
docker / docker-test (push) Successful in 8s
docker / docker-publish (push) Successful in 7s
Reviewed-on: #8
2026-02-27 19:29:16 +00:00
Latte 822b83e618 Merge pull request 'update/image-build-workflow' (#7) from update/image-build-workflow into dev
docker / docker-publish (push) Successful in 7s
docker / lint (push) Successful in 22s
docker / test (push) Successful in 18s
lint / lint (push) Successful in 24s
test / test (push) Successful in 19s
docker / docker-test (push) Successful in 8s
docker / lint (pull_request) Successful in 1m31s
docker / test (pull_request) Successful in 18s
lint / lint (pull_request) Successful in 24s
test / test (pull_request) Successful in 20s
docker / docker-test (pull_request) Successful in 38s
docker / docker-publish (pull_request) Has been skipped
Reviewed-on: #7
2026-02-27 18:59:23 +00:00
Latte 2f9750dcce Return explicit error for tokens lacking scopes
lint / lint (push) Successful in 24s
test / test (push) Successful in 19s
docker / lint (pull_request) Successful in 23s
docker / test (pull_request) Successful in 18s
lint / lint (pull_request) Successful in 24s
test / test (pull_request) Successful in 20s
docker / docker-test (pull_request) Successful in 39s
docker / docker-publish (pull_request) Has been skipped
2026-02-27 19:55:01 +01:00
Latte 5b4495a0a9 updaAdd AI review workflowste
lint / lint (push) Successful in 23s
test / test (push) Failing after 19s
2026-02-27 19:47:54 +01:00
Latte fc93b8d29e Fix Prometheus metric f-string and add YAML helper
lint / lint (push) Successful in 23s
test / test (push) Failing after 20s
2026-02-27 16:08:17 +01:00
Latte c0357ceb69 Add configurable registry push to Docker workflow
lint / lint (push) Failing after 2m15s
test / test (push) Failing after 11s
2026-02-27 15:50:12 +01:00
Latte fa30153c0d Enhance Docker workflow with gated publish
lint / lint (push) Has been cancelled
test / test (push) Has been cancelled
Expand workflow triggers to push/pull_request on main and dev and to PR
reviews. Run lint/test only for non-review events or when a review is
approved. Add a docker-test job that smoke-tests the built image. Add a
docker-publish job that resolves SHA and stable tags (latest/dev),
builds
the releasable image, and optionally pushes when PUSH_IMAGE=true. Update
docs/deployment.md
2026-02-27 11:02:48 +01:00
Latte c79cc1ab9e Add PUBLIC_BASE_URL and refine OAuth scopes
docker / lint (push) Has been cancelled
docker / test (push) Has been cancelled
docker / docker-build (push) Has been cancelled
lint / lint (push) Has been cancelled
test / test (push) Has been cancelled
2026-02-25 20:49:08 +01:00
Latte 59e1ea53a8 Add OAuth2/OIDC per-user Gitea authentication
docker / lint (push) Has been cancelled
docker / test (push) Has been cancelled
docker / docker-build (push) Has been cancelled
lint / lint (push) Has been cancelled
test / test (push) Has been cancelled
Introduce a GiteaOAuthValidator for JWT and userinfo validation and
fallbacks, add /oauth/token proxy, and thread per-user tokens through
the
request context and automation paths. Update config and .env.example for
OAuth-first mode, add OpenAPI, extensive unit/integration tests,
GitHub/Gitea CI workflows, docs, and lint/test enforcement (>=80% cov).
2026-02-25 16:54:01 +01:00
Latte a00b6a0ba2 update 2026-02-14 18:18:34 +01:00
Latte ecc87cbb65 quick fix 2026-02-14 17:18:30 +01:00