Summary
Deleting an Unleash instance from Console is refused for any instance with more than one allowed team. Until today that was an inescapable state, because revoking team access was a silent no-op — so the only way out of the gate was through a door that did not work.
Severity: high — a user-facing action was impossible to complete
Component: src/routes/team/[team]/unleash/+page.svelte:307-308, and server-side in nais-api internal/unleash/models.go:183
Mechanism
The UI gate:
const allowedTeamsCount = $derived(unleash?.allowedTeams.edges.length ?? 0);
const canDelete = $derived(allowedTeamsCount === 1 && unleash?.ready);
with the message "Revoke access for all other teams before deleting. Currently N other teams have access." nais-api enforces the same rule server-side.
The owner team counts toward that total, so === 1 means "only the owner". Any instance that ever granted access to a second team needs a revoke before it can be deleted.
Revoking was broken: nais/bifrost#567 — allowed_teams could only ever grow, because bifrost unioned it with allowed_namespaces and wrote the union back to both fields. The instance therefore could never return to a single team, and Delete stayed disabled forever with a message telling the user to do something that silently did nothing.
Current state
66 instances in production:
|
|
| Deletable (owner only) |
49 |
| Blocked (more than one team) |
17 |
| Not ready |
0 |
Readiness is not a factor for any of them.
Status
The revoke fix (nais/bifrost#568) merged and deployed today, so the 17 blocked instances can now be unblocked by revoking the extra teams first. This should be re-tested before any further work — the delete path itself may be entirely healthy.
What is still worth fixing
Even with revoke working, the flow is poor: the user is shown a disabled button and told to go revoke, with no link to where, and no feedback if the revoke fails. #567 added error surfacing to the revoke path, which helps, but the delete gate could say which teams are blocking it and link to them.
Acceptance criteria
Summary
Deleting an Unleash instance from Console is refused for any instance with more than one allowed team. Until today that was an inescapable state, because revoking team access was a silent no-op — so the only way out of the gate was through a door that did not work.
Severity: high — a user-facing action was impossible to complete
Component:
src/routes/team/[team]/unleash/+page.svelte:307-308, and server-side in nais-apiinternal/unleash/models.go:183Mechanism
The UI gate:
with the message "Revoke access for all other teams before deleting. Currently N other teams have access." nais-api enforces the same rule server-side.
The owner team counts toward that total, so
=== 1means "only the owner". Any instance that ever granted access to a second team needs a revoke before it can be deleted.Revoking was broken: nais/bifrost#567 —
allowed_teamscould only ever grow, because bifrost unioned it withallowed_namespacesand wrote the union back to both fields. The instance therefore could never return to a single team, and Delete stayed disabled forever with a message telling the user to do something that silently did nothing.Current state
66 instances in production:
Readiness is not a factor for any of them.
Status
The revoke fix (nais/bifrost#568) merged and deployed today, so the 17 blocked instances can now be unblocked by revoking the extra teams first. This should be re-tested before any further work — the delete path itself may be entirely healthy.
What is still worth fixing
Even with revoke working, the flow is poor: the user is shown a disabled button and told to go revoke, with no link to where, and no feedback if the revoke fails. #567 added error surfacing to the revoke path, which helps, but the delete gate could say which teams are blocking it and link to them.
Acceptance criteria
DELETE /v1/unleash/{name}response and reopen with it.