Skip to content

cd: gate the client-api on the fint version headers where core 1 still serves V3 - #124

Merged
nozoz merged 6 commits into
developfrom
feat/gate-client-api-on-model-version
Oct 16, 2026
Merged

nozoz merged 6 commits into
developfrom
feat/gate-client-api-on-model-version

Conversation

@nozoz

@nozoz nozoz commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Why

Today the vlfk and oslo api overlays sent every /utdanning request for those orgs to the client-api regardless of version headers, because the base IngressRoute gated only /okonomi. Traefik v2 ranks by rule length, so the long client-api rule beat the short core 1 path rule and V3 clients hit V4.

What production serves today (api cluster, 659 live routers)

Package Core 1 (V3, all orgs) Old core 2 consumer Client-api rule now
utdanning elev, kodeverk, timeplan, utdanningsprogram, vurdering yes 13 counties, V4 header only gated on V4
okonomi faktura, kodeverk yes none gated on V4
utdanning larling, ot no 13 counties, no header ungated
okonomi regnskap no 8 orgs, no header ungated
personvern, ressurs, felles except kodeverk no few orgs / none, no header ungated
felles/kodeverk, arkiv, profilbilde, provider paths yes none not claimed
administrasjon yes 6 orgs, no header only via components/administrasjon, wholesale

Changes

  • Rule (kustomize/base/consumer-ingress.yaml): the client-api takes a request on the seven core 1 packages only when the client asks for V4. x-fint-model-version-override or x-fint-version-override wins when v3 or v4; otherwise x-fint-model-version decides; no headers falls through to core 1. Case-insensitive. Both override spellings are honoured because x-fint-model-version-override is what the core 2 routes and fint-link-walker use. All other claimed packages are ungated. The org regex moves to backtick index 19 in components/org. The shared novari route in beta gets the same gate.
  • Test (kustomize/rules-test/, workflow Ingress rules): renders every overlay with kustomize, runs the real Traefik v2.11.2 in Docker with whoami backends and a lowest-priority catch-all for core 1, and sends a matrix of org, path and header combinations. 4997 checks across 31 overlays pass; against develop's current rule 579 fail, the first being vlfk utdanningsprogram with no headers reaching the client-api.
  • Disabled api overlays: the 13 counties still on the old core 2 consumer get <org>.disabled overlays copied from beta. CD skips *.disabled, so only vlfk and oslo deploy. kustomize/overlays/api/README.md explains that the old core 2 consumers for an org must be removed before renaming its overlay.

Notes

  • Beta has utdanning disabled in core 1, so a header-less utdanning request in beta now gets a 404 instead of V4 data. Beta clients must send the V4 header.
  • The old core 2 consumer manifests for vlfk and ude-oslo-kommune-no still sit in fint-infra-tools api/core2/ although they are not applied in the cluster. They should be deleted there.
  • Needs to reach main before any other push to main, since any push recreates the client-api Applications with whatever rule is on main.

🤖 Generated with Claude Code

nozoz and others added 6 commits October 16, 2026 15:53
… still serves V3

In the api cluster core 1 still serves seven packages as V3: utdanning
elev, kodeverk, timeplan, utdanningsprogram and vurdering, and okonomi
faktura and kodeverk. The core 2 consumer routes for those packages only
take a request that asks for V4. The client-api route gated only
/okonomi, so every utdanning request for an org went to the client-api
regardless of the version headers.

The route now gates exactly those seven packages:
x-fint-model-version-override or x-fint-version-override wins when it
is v3 or v4. If neither override is set, x-fint-model-version decides.
With no headers the request falls through to core 1. Values are matched
without regard to case. x-fint-model-version-override is the spelling
the core 2 routes and clients such as fint-link-walker use.

Every other package the route claims has no V3 consumer in production
(utdanning larling and ot, okonomi regnskap, personvern, ressurs, felles
apart from kodeverk) and goes to the client-api whatever the headers.
felles/kodeverk and provider paths stay out. The shared novari route in
beta gets the same gate. The administrasjon route is left ungated, as
its core 2 routes in production are.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
kustomize/rules-test renders the client-api IngressRoute of every overlay
(alpha excluded, it has no core 1) into a Traefik file-provider config,
with a lowest-priority catch-all per host standing in for core 1. A
docker compose file runs Traefik v2.11.2, the version in the clusters,
with whoami backends, and test.sh sends a matrix of org, path and
version-header combinations and checks which backend answers: on the
seven packages core 1 still serves as V3, V3 clients never reach the
client-api and V4 clients always do; packages without a V3 consumer go
to the client-api whatever the headers; felles/kodeverk and provider
paths never do; administrasjon goes wholesale only where an overlay
says so.

The Ingress rules workflow runs it on every pull request and push that
touches kustomize.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The 13 counties still on the old core 2 consumer get an api overlay
named <org>.disabled, copied from their beta overlay with the api host,
base-url and vault. CD skips *.disabled when it discovers overlays, so
only vlfk and oslo deploy. The rules test still renders and checks the
disabled overlays, so they are verified before anyone enables one.

kustomize/overlays/api/README.md says what to do before renaming one:
remove the old core 2 consumers for that org first.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The network gateway injects x-allowed-asset-ids from the adapter's token,
and the per-org fint-core-adapter-gateway routes match on that header.
The script gets a token with the adapter's credentials the way
fint-core-adapter-common does, prints the assets in it, calls
/provider/status through the network gateway and tells the new
adapter-gateway (its greeting body and principal) from the old
provider-gateway.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The old provider-gateway returns the same /provider/status greeting as
the adapter-gateway, so the response cannot show which one answered.
The script now posts an adapter contract to /provider/register through
the ingress with $TOKEN, then compares the adapter-gateway's request
counter for that path, read through the Kubernetes API proxy, before
and after, and greps the old gateway's log for the contract.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nozoz
nozoz merged commit d55f77a into develop Oct 16, 2026
8 checks passed
@nozoz
nozoz deleted the feat/gate-client-api-on-model-version branch October 16, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant