> ## Documentation Index
> Fetch the complete documentation index at: https://docs.internal.nscale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Relationship: UNI resource attribution

> The UNI Region, Kubernetes and Identity APIs the OpenStack agent resolves Nova instances against to record who a device is attributed to.

* **Kind:** Observation
* **Version:** 1
* **Fleet Manager owner:** Fleet Manager squad, #fleet-manager-chat (individual claimant pending)
* **Counterpart owner:** unassigned (UNI Region, Kubernetes and Identity services are owned by Platform Services)
* **Last reviewed:** 2026-09-14

## What flows

The per-satellite OpenStack agent (`src/fleet_manager/agents/openstack/`, wire identity `ironic-agent`) resolves each
assigned [Nova](../start-here/glossary#nova) server's metadata against three UNI APIs (`src/fleet_manager/agents/openstack/resource_attribution.py`):
the Region API for the UNI instance, the Kubernetes API for a managed [cluster](../start-here/glossary#cluster), and the Identity API for the owning
project and organisation. The result is posted to `inventory/resource-attributions/materialise/` as a
`DeviceResourceBinding` (ADR-0037), with unassigned nodes and missing servers recorded explicitly rather than
skipped. It runs on the reconciler's node pass and on the assigned-node sweep (`assigned_node_sweep_interval`,
default 300 s). A malformed or unavailable UNI response is a retryable lookup failure that keeps the previous
attribution; nothing is cleared on a bad read.

The path is gated per site: `uni.enabled` in the satellite chart defaults false, and when it is enabled all three base
URLs and the mTLS credential Secret must be set or the agent refuses to start. On chart defaults the agent runs
without UNI clients and writes no attribution. Fleet Manager reads only; it never writes into UNI.

## What breaks if this changes

A UNI API shape change or outage stops attribution refresh for the site; bindings freeze at their last value and
`resolution_status` records the failure kind. A Nova metadata convention change (which keys carry the UNI instance
and cluster ids) silently attributes nothing, because the resolver reports not-found rather than erroring. [Radar](../start-here/glossary#radar-api) and
org-service read the resulting bindings, so a stale binding shows up as wrong customer attribution downstream.

## Enforcement

* **Principal:** the satellite `ironic-agent` (towards Fleet Manager) and the site's UNI client certificate (towards
  UNI).
* **Mechanism:** towards Fleet Manager, the `ironic-agent` FM OAuth client (private-key JWT) in the satellite roster
  holding `resource-attribution:write`, checked by `ResourceAttributionWritePermissions`
  (`src/fleet_manager/api/auth/permissions.py`); towards UNI, mTLS with the certificate, key and CA from the Secret
  named by `uni.credentialsSecretName`, mounted at `/etc/uni-certs`.
* Settings: `src/fleet_manager/settings/clients/uni.py` (`enabled`, base URLs, TLS paths, timeouts).

## Gaps

* No counterpart owner or notice period for UNI API changes.
* No contract test against the UNI APIs; the resolver's expectations of the response shapes live only in its tests.

## Change log

* 2026-09-14 v1: created after the writer landed on main (#2867); describes present behaviour.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.