From 05aaf28be583a5b99cc78eb7225dc2b0d7cdad2a Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Sun, 1 Nov 2026 15:09:52 -0500 Subject: [PATCH 1/2] fix: sync the bundled adapter manifest with API 0.21.1 The bundled copy was the API 0.19.4 manifest, so in fallback mode the v0.21 application, resource and OAuth provider discovery admin routes answered 404. Refs #28 --- manifest.json | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 5eda92a..05919e8 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "apiVersion": "0.19.4", + "apiVersion": "0.21.1", "session": { "subject": "sub", "token": "token", @@ -9,6 +9,15 @@ "refreshTtl": "refreshTtl" }, "routes": [ + { "method": "GET", "path": "/admin/applications", "credential": "access" }, + { "method": "POST", "path": "/admin/applications", "credential": "access" }, + { "method": "DELETE", "path": "/admin/applications/{id}", "credential": "access" }, + { "method": "GET", "path": "/admin/applications/{id}", "credential": "access" }, + { "method": "PATCH", "path": "/admin/applications/{id}", "credential": "access" }, + { "method": "PUT", "path": "/admin/applications/{id}/keys", "credential": "access" }, + { "method": "GET", "path": "/admin/applications/{id}/resources", "credential": "access" }, + { "method": "PUT", "path": "/admin/applications/{id}/resources", "credential": "access" }, + { "method": "POST", "path": "/admin/applications/{id}/secret", "credential": "access" }, { "method": "GET", "path": "/admin/auth-events", "credential": "access" }, { "method": "GET", "path": "/admin/auth-events/export", "credential": "access" }, { "method": "GET", "path": "/admin/auth-events/integrity", "credential": "access" }, @@ -51,6 +60,11 @@ "credential": "access" }, { "method": "GET", "path": "/admin/reports/authentication-coverage", "credential": "access" }, + { "method": "GET", "path": "/admin/resources", "credential": "access" }, + { "method": "POST", "path": "/admin/resources", "credential": "access" }, + { "method": "DELETE", "path": "/admin/resources/{id}", "credential": "access" }, + { "method": "GET", "path": "/admin/resources/{id}", "credential": "access" }, + { "method": "PATCH", "path": "/admin/resources/{id}", "credential": "access" }, { "method": "GET", "path": "/admin/review-accounts", "credential": "access" }, { "method": "GET", "path": "/admin/sessions", "credential": "access" }, { "method": "GET", "path": "/admin/sessions/{userId}", "credential": "access" }, @@ -219,6 +233,11 @@ { "method": "POST", "path": "/system-config/oauth-providers", "credential": "access" }, { "method": "DELETE", "path": "/system-config/oauth-providers/{id}", "credential": "access" }, { "method": "PATCH", "path": "/system-config/oauth-providers/{id}", "credential": "access" }, + { + "method": "POST", + "path": "/system-config/oauth-providers/{id}/discovery", + "credential": "access" + }, { "method": "GET", "path": "/system-config/policy", "credential": "access" }, { "method": "DELETE", "path": "/system-config/policy/draft", "credential": "access" }, { "method": "PUT", "path": "/system-config/policy/draft", "credential": "access" }, From 923cf7bce5df3ccdac573f08785504b9f86d5b7a Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Sun, 1 Nov 2026 15:09:52 -0500 Subject: [PATCH 2/2] ci: fail when the bundled manifest drifts from the API Closes #28 --- .github/workflows/manifest.yml | 22 +++++++++++++++++ AGENTS.md | 4 +++ scripts/check-manifest.sh | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 .github/workflows/manifest.yml create mode 100755 scripts/check-manifest.sh diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml new file mode 100644 index 0000000..8d9775e --- /dev/null +++ b/.github/workflows/manifest.yml @@ -0,0 +1,22 @@ +name: manifest + +# The bundled adapter manifest must match the one seamless-auth-api main +# publishes. The schedule catches API route changes that land between PRs here. +on: + push: + branches: [main] + pull_request: + schedule: + - cron: '17 6 * * *' + workflow_dispatch: + +permissions: + contents: read + +jobs: + drift: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - run: scripts/check-manifest.sh diff --git a/AGENTS.md b/AGENTS.md index c17f060..4d93d5c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,6 +53,7 @@ guidance may extend them but must not contradict them. | Tests | `cargo test` | | MSRV | `cargo +1.88 test` | | Conformance | see README, "Conformance" | +| Manifest | `scripts/check-manifest.sh` (fix with `scripts/sync-manifest.sh`) | The crate targets Rust 1.88 (`rust-version` in `Cargo.toml`), set by jsonwebtoken 11. Do not use language or standard library features newer than that (CI runs 1.88). `Cargo.lock` is committed @@ -100,5 +101,8 @@ version, edit the changelog's released sections, or tag by hand: did not declare. - Merging that PR tests the crate, publishes it to crates.io through trusted publishing (no token in the repository), tags `vX.Y.Z`, and creates the GitHub release. +- The bundled manifest must match the one seamless-auth-api main publishes. The `manifest` + workflow checks it on every PR, on `main` and daily. Update it with `scripts/sync-manifest.sh` + in a `fix:` commit so the new routes ship in a patch release. Pre-1.0: a breaking change is a minor bump, and 1.0 is a deliberate decision, not a side effect. diff --git a/scripts/check-manifest.sh b/scripts/check-manifest.sh new file mode 100755 index 0000000..84896ab --- /dev/null +++ b/scripts/check-manifest.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env sh +# Fails when the bundled adapter manifest differs from the one the auth API +# publishes. The bundled copy is what the adapter serves whenever the live fetch +# fails, so a route missing from it answers 404 in that case. apiVersion is +# ignored: it changes on every API release, routes do not. +# +# scripts/check-manifest.sh [source] +# +# source defaults to seamless-auth-api main. Fix a failure with +# scripts/sync-manifest.sh. +set -eu + +source="${1:-https://raw.githubusercontent.com/fells-code/seamless-auth-api/main/adapter-manifest.json}" +bundled="$(dirname "$0")/../manifest.json" + +dir="$(mktemp -d)" +trap 'rm -rf "$dir"' EXIT + +case "$source" in + http://*|https://*) curl -fsSL "$source" -o "$dir/upstream.json" ;; + *) cp "$source" "$dir/upstream.json" ;; +esac + +normalize() { jq -S 'del(.apiVersion) | .routes |= sort_by(.path, .method)' "$1"; } +normalize "$bundled" > "$dir/bundled.norm" +normalize "$dir/upstream.json" > "$dir/upstream.norm" + +if cmp -s "$dir/bundled.norm" "$dir/upstream.norm"; then + echo "Bundled manifest matches $source" + exit 0 +fi + +routes() { jq -r '.routes[] | "\(.method) \(.path)"' "$1" | sort; } +routes "$bundled" > "$dir/bundled.routes" +routes "$dir/upstream.json" > "$dir/upstream.routes" + +echo "Bundled manifest (manifest.json) differs from $source" >&2 +echo "Missing from the bundled copy:" >&2 +comm -13 "$dir/bundled.routes" "$dir/upstream.routes" | sed 's/^/ /' >&2 +echo "Only in the bundled copy:" >&2 +comm -23 "$dir/bundled.routes" "$dir/upstream.routes" | sed 's/^/ /' >&2 +echo "Full difference:" >&2 +diff -u "$dir/bundled.norm" "$dir/upstream.norm" >&2 || true +echo "Run scripts/sync-manifest.sh to update it." >&2 +exit 1