Skip to content

api-test-v1.1.1

Choose a tag to compare

@github-actions github-actions released this 12 May 23:57
· 2 commits to main since this release
Immutable release. Only release title and notes can be modified.
a9e161b

Highlights

Bug-fix release. Two defects in v1.1.0 were visible on every fresh deployment — the audit detail panel rendered captured bodies as base64 strings, and the portal Try-It widget returned 401 missing credential for a logged-in operator. Both are fixed here.

Fixes

Audit detail bodies now render as decoded JSON, not base64

audit_payloads.request_body / response_body are stored as BYTEA. Go's default JSON encoder emits []byte as base64, so the portal's audit detail panel was showing operators a wall of base64 instead of the captured request and response.

Payload.MarshalJSON now emits utf-8 bodies as JSON strings (the SPA's existing tryParseJSON then renders them as pretty-printed JSON). Non-utf-8 bodies fall back to base64 with a sibling request_body_encoding=base64 / response_body_encoding=base64 flag so binary payloads round-trip unambiguously.

// v1.1.0 — what audit detail showed
"request_body": "eyJoZWxsbyI6Indvcmxk..."

// v1.1.1
"request_body": "{\"hello\":\"world\",\"n\":42}"

Try-It returns 200 when you're logged in

The Try-It dispatcher re-enters the local mux via replayTarget.ServeHTTP, but the dispatched request carried no credential header (Try-It deliberately strips operator-supplied Authorization/Cookie). The inbound auth middleware would 401 a request the portal had already accepted via session cookie.

portal_tryit now translates the portal-resolved auth.Identity into an inbound.Identity on the dispatched context, and httpmw.Identity short-circuits the chain when one is already present. The bypass yields when a real credential is on the wire — so typing X-API-Key: <other-key> into the Try-It headers field to "test as a different principal" still resolves through the chain.

Audit replay no longer 401s on redacted credentials

The audit middleware redacts Authorization / X-API-Key / Cookie header values and ?api_key= query values to the string [redacted] before persisting. Replaying a captured request verbatim would put [redacted] on the wire, which the inbound chain rejected as an invalid credential.

The replay handler now drops those credential headers and the api_key query param before re-emission and carries identity through the dispatched context — the same trust model as Try-It.

Tests

  • Payload.MarshalJSON: utf-8, binary, empty cases.
  • httpmw.Identity: pre-set bypass; wire-credential override of pre-set.
  • portal_audit_replay: end-to-end through the real httpmw.Identity middleware with a chain that rejects [redacted] — would 401 if the redacted-header filter ever regresses.

Known limitation

hasInboundCredential and the replay handler's redacted-header filter hardcode the default api-key header/query names (X-API-Key, api_key). Deployments that customize APIKeysConfig.HeaderName / QueryParamName will silently lose Try-It "test as someone else" semantics under the custom name, and replay will leak the captured redaction sentinel for the custom header. The reference api-test-server.plexara.io deployment runs the defaults, so this isn't a regression for the typical rollout. Follow-up will either thread the configured names through Identity() or add a HasCredential(r) method to inbound.Chain that each authenticator implements. Tracked in code with TODO markers at both call sites.

Changelog

  • 19021e7: audit,portal: render bodies as utf-8 strings; propagate identity through Try-It and replay dispatch (@cjimti)

Installation

Container

docker pull ghcr.io/plexara/api-test:v1.1.1

Binary (macOS / Linux)

curl -L -o api-test.tar.gz \
  https://github.com/plexara/api-test/releases/download/v1.1.1/api-test_1.1.1_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz
tar -xzf api-test.tar.gz
./api-test --version

Documentation

Full docs at https://api-test.plexara.io.

Open source by Plexara, the commercial MCP + API gateway with configurable enrichment built in.