From 6a54ca62d2eed2b87ba68012d63f9c37e421409e Mon Sep 17 00:00:00 2001 From: Marco Fanti Date: Thu, 30 Jul 2026 16:31:15 -0400 Subject: [PATCH 1/3] ci: add GitHub Actions workflow and prek hooks --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ .pre-commit-config.yaml | 18 ++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..28d47c7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 + with: + distribution: temurin + java-version: '26' + cache: maven + + # Interop tests skip themselves when the aauth-python-library checkout is absent. + - name: Build and verify + run: mvn -B --no-transfer-progress verify diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..3286b28 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,18 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-merge-conflict + - id: check-added-large-files + + - repo: local + hooks: + - id: spotless-check + name: spotless format check + entry: mvn -q spotless:check + language: system + files: \.java$ + pass_filenames: false From f6fe445cdc905464f2ed40dd93ed7b03ca1b1738 Mon Sep 17 00:00:00 2001 From: Marco Fanti Date: Thu, 30 Jul 2026 16:36:04 -0400 Subject: [PATCH 2/3] test: fall back to 127.0.0.1 when uma.lab hostnames don't resolve (CI) --- .../io/github/marcofanti/aauth/TestHosts.java | 28 +++++++++++++++++++ .../aauth/agent/TokenExchangeTest.java | 3 +- .../aauth/keys/DefaultHttpClientTest.java | 3 +- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 aauth/src/test/java/io/github/marcofanti/aauth/TestHosts.java diff --git a/aauth/src/test/java/io/github/marcofanti/aauth/TestHosts.java b/aauth/src/test/java/io/github/marcofanti/aauth/TestHosts.java new file mode 100644 index 0000000..1f99616 --- /dev/null +++ b/aauth/src/test/java/io/github/marcofanti/aauth/TestHosts.java @@ -0,0 +1,28 @@ +package io.github.marcofanti.aauth; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Hostname selection for live-socket tests. + * + *

Lab hostnames ({@code *.uma.lab}) resolve to 127.0.0.1 on development machines; CI runners + * cannot resolve them. Tests use the lab name when it resolves to a loopback address (never a + * real remote host) and fall back to {@code 127.0.0.1} otherwise. + */ +public final class TestHosts { + + private TestHosts() {} + + /** Returns {@code preferred} when it resolves to loopback; {@code 127.0.0.1} otherwise. */ + public static String loopbackHost(String preferred) { + try { + if (InetAddress.getByName(preferred).isLoopbackAddress()) { + return preferred; + } + } catch (UnknownHostException e) { + // Not resolvable here (e.g. CI) — use the literal loopback address. + } + return "127.0.0.1"; + } +} diff --git a/aauth/src/test/java/io/github/marcofanti/aauth/agent/TokenExchangeTest.java b/aauth/src/test/java/io/github/marcofanti/aauth/agent/TokenExchangeTest.java index bcc00b3..1b2ea39 100644 --- a/aauth/src/test/java/io/github/marcofanti/aauth/agent/TokenExchangeTest.java +++ b/aauth/src/test/java/io/github/marcofanti/aauth/agent/TokenExchangeTest.java @@ -32,7 +32,8 @@ class TokenExchangeTest { void startServer() throws Exception { server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0); server.start(); - base = "http://ps.uma.lab:" + server.getAddress().getPort(); + base = "http://" + io.github.marcofanti.aauth.TestHosts.loopbackHost("ps.uma.lab") + ":" + + server.getAddress().getPort(); } @AfterEach diff --git a/aauth/src/test/java/io/github/marcofanti/aauth/keys/DefaultHttpClientTest.java b/aauth/src/test/java/io/github/marcofanti/aauth/keys/DefaultHttpClientTest.java index 9b76646..487165b 100644 --- a/aauth/src/test/java/io/github/marcofanti/aauth/keys/DefaultHttpClientTest.java +++ b/aauth/src/test/java/io/github/marcofanti/aauth/keys/DefaultHttpClientTest.java @@ -38,7 +38,8 @@ static void startServer() throws Exception { } }); server.start(); - baseUrl = "http://grafana.uma.lab:" + server.getAddress().getPort(); + baseUrl = "http://" + io.github.marcofanti.aauth.TestHosts.loopbackHost("grafana.uma.lab") + ":" + + server.getAddress().getPort(); } @AfterAll From 7e2eb70054aa355a573b53cbb678b5d16f916527 Mon Sep 17 00:00:00 2001 From: Marco Fanti Date: Thu, 30 Jul 2026 23:13:08 -0400 Subject: [PATCH 3/3] docs: record remote, CI setup and hostname fallback; add CI badge --- CLAUDE.md | 3 +++ README.md | 2 ++ Summary.md | 2 +- docs/PROGRESS.md | 12 ++++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index c512bd9..814b6d8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,6 +16,9 @@ implementation — mirror its behavior, module split, and README structure. - JDK 26 target (`--release 26`); Java 26+ required (user decision 2026-07-30). - Build: `mvn verify` (runs tests, JaCoCo 80% line-coverage gate, Spotless check). - Format: `mvn spotless:apply` (Palantir Java Format) before committing. +- Hooks: prek is installed (`prek run` runs whitespace/YAML checks + spotless:check). +- Remote: https://github.com/marcofanti/aauth-java-library — never push directly to main; + use feature branches and PRs. CI runs `mvn verify` on JDK 26. - Zero warnings: compiler runs `-Xlint:all,-serial,-processing -Werror`. - Immutable value types (records) for parsed headers, claims, results. - No framework dependencies in the core; HTTP via JDK `java.net.http` behind interfaces. diff --git a/README.md b/README.md index b2b2594..8f0a004 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # aauth-java-library +[![CI](https://github.com/marcofanti/aauth-java-library/actions/workflows/ci.yml/badge.svg)](https://github.com/marcofanti/aauth-java-library/actions/workflows/ci.yml) + Java implementation of the [AAuth protocol](https://github.com/dickhardt/AAuth) — an authorization protocol for agent-to-resource access built on HTTP Message Signatures (RFC 9421) and JWT-based proof-of-possession tokens. diff --git a/Summary.md b/Summary.md index 3f36de2..bf32e5d 100644 --- a/Summary.md +++ b/Summary.md @@ -1,6 +1,6 @@ # aauth-java-library -**Source:** authored locally (not a clone) — port of https://github.com/christian-posta/aauth-python-library +**Source:** https://github.com/marcofanti/aauth-java-library (authored locally) — port of https://github.com/christian-posta/aauth-python-library **Stack:** Java 26, Maven multi-module (io.github.marcofanti:aauth-signing, io.github.marcofanti:aauth) Java implementation of the AAuth protocol (github.com/dickhardt/AAuth) — agent-to-resource diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 8c489de..05db5e9 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -52,6 +52,18 @@ All crypto/verification paths (signature schemes, token verification order, Ed25 encoding, P1363/DER handling, JWKS discovery) were confirmed equivalent to the Python reference with no findings. +## Post-completion (2026-07-30, after initial push) + +- Repo published at https://github.com/marcofanti/aauth-java-library (pushed by the user). +- **CI added** (PR #1): GitHub Actions workflow running `mvn verify` on JDK 26 (Temurin), + actions SHA-pinned, `persist-credentials: false`, read-only permissions; validated with + actionlint and zizmor. Interop tests self-skip in CI (no Python checkout). +- **prek hooks added**: whitespace/EOF/YAML/merge-conflict/large-file checks + local + `spotless:check`; installed via `prek install`. +- **CI portability fix**: live-socket tests resolve `*.uma.lab` hostnames only when they map + to loopback (see `TestHosts`); CI runners fall back to `127.0.0.1`. First CI run failed on + unresolvable lab hostnames; second run green. + ## Test fixtures Per user request (2026-07-30), test fixtures and examples use the local UMA lab hostnames