Identity Security Considerations
MIAF assumes an adversarial network and the possibility of a compromised individual device or service. Its goals are to preserve identity integrity and minimize blast radius; protecting the private keys those identities rest on is the responsibility of the deployment rather than provided by the framework.
This section is scoped to identity. For each threat, it describes the mitigation that MIAF relies on, along with links to the specific rules. Some mitigations are normative framework requirements; others are residual risks carried by the operator's deployment. The threat tables state no requirements of their own. Each normative mitigation is stated on the page the table links to.
Framework Threats
| Threat | Description | Mitigation |
|---|---|---|
| Theft and misuse of a credential | An attacker who obtains a principal's SVID together with its private key authenticates as that principal anywhere its SPIFFE ID is accepted; an X.509-SVID carries no audience restriction confining it to one verifier. | The protection of the private key is covered in the private-key-compromise row below. Short SVID lifetimes limit the exposure window (see SVID lifetime guidance). Each verifier validates the SVID against the Trust Bundle and authorizes the specific SPIFFE ID locally, so a stolen credential reaches only what that identity is granted (see X.509-SVID validation). |
| Private key compromise | An attacker exfiltrates a principal's private key and can then authenticate as that principal until the credential is withdrawn. | A principal protects its private key per deployment policy; MIAF specifies no key-protection mechanism of its own. The operator provisioning playbook's preferred path issues by CSR, which keeps the key on the principal and can bind it to hardware (TPM, secure element, or HSM) where available. Once compromise is known, access is withdrawn via the operator revocation playbook, bounded by short SVID lifetimes. |
| Central key-custody concentration | Where a principal cannot generate its own key pair, the operator generates it centrally (see operator provisioning playbook), concentrating many principals' private keys in one store whose breach exposes all of them at once. | The provisioning playbook's preferred path generates the key on the principal (issuance by CSR), leaving no central copy; where a principal cannot generate its own key pair, the operator generates it centrally and accepts the resulting key-custody concentration risk, protecting the store per deployment policy and treating its breach as private-key compromise (row above). |
| Compromised issuance authority (MIS) | A compromised MIS can mint a valid SVID for any SPIFFE ID in the Trust Domain, impersonating any WFM or client, or issue under a WFM namespace at will. | MIAF concentrates issuance in the MIS by design, so protecting it is an operator PKI-governance responsibility: scope the issuing authority (for example an intermediate CA per the deployment patterns) and protect its signing key per deployment policy. Recovery is Trust Bundle rotation to retire the compromised authority. |
| Initial trust anchor confusion | An attacker causes a principal to trust the wrong HTTPS authority and serves a malicious discovery document or Trust Bundle. | A principal authenticates the first HTTPS retrieval of the discovery document and trustBundleUri, per initial trust bootstrap. |
| Trust Bundle substitution or anchor injection | An attacker who compromises a Trust Bundle origin (or its server certificate) injects a trust anchor. Because the SPIFFE bundle is authenticated only by the transport and is not itself signed, every SVID chaining to the injected anchor is then accepted. This applies on every refresh, not only at bootstrap. | A client retrieves the Trust Bundle only over HTTPS validated against its configured initial-trust anchors or pins, on each refresh, per initial trust bootstrap and certificate validation, and fails closed on an empty or unusable bundle, per selecting and refreshing the bundle. A client anchored on a public PKI accepts a trustBundleUri from the discovery document only at the origin of that document, per the Trust Bundle retrieval endpoint rules. A valid certificate for another public name is therefore not sufficient. Integrity of the cached copy is covered in the local-tampering row below. |
| Trust Bundle rollback | A stale, cached, or replayed Trust Bundle is served to reverse a completed rotation, re-admitting a trust anchor that was removed to revoke a compromise. | A client authenticates every Trust Bundle retrieval, not only the first, per initial trust bootstrap, so a third party cannot substitute an older bundle. The refresh interval overrides HTTP cache freshness, so a cached copy cannot outlive that interval (see selecting and refreshing the bundle). These controls do not stop an authenticated origin, a cache, or a proxy in front of the MIS from serving an older bundle. A decrease of spiffe_sequence is logged and signaled, but the bundle is not rejected, per bundle ordering. |
| Blocked Trust Bundle refresh | A client cannot refresh its Trust Bundle, because an attacker denies it network access or because the device is intermittently connected or offline by design. The client keeps validating SVIDs against its cached anchors and never learns that an anchor was retired, so a compromised issuing authority under that anchor can keep minting SVIDs the client accepts. Short SVID lifetimes do not help, because the compromised authority can mint fresh ones. | MIAF sets no upper bound on bundle staleness and accepts this residual risk. A client caches its bundle to validate SVIDs while offline (see bundle contents and distribution), so a client that failed closed on a stale bundle would stop validating its WFM during any connectivity outage. The exposure requires the attacker to reach the client and to hold an SVID issued under the retired anchor, and it ends at the next successful refresh. An operator that needs a staleness bound sets one in deployment policy. A client signals a bundle older than an operator-configured threshold, per selecting and refreshing the bundle, so the condition is visible to the operator. |
| Reused SPIFFE ID after principal replacement | A principal is decommissioned rather than compromised, so nobody withdraws its SVID, and its SPIFFE ID is reused for the replacement. The retired SVID stays valid until it expires, and its private key may be recoverable from decommissioned or resold hardware, so the retired principal can still authenticate as the shared identity. | An operator assigns a fresh SPIFFE ID to the replacement unless the retired private key is known to be destroyed, per the operator provisioning playbook. While the two share an identity, allowlist removal cannot separate them, so the exposure otherwise lasts until the retired SVID expires (see SVID lifetime guidance). |
| Certificate revocation lag | A revocation event is not propagated promptly. | A deployment relies on the operator revocation playbook and short SVID lifetimes. A verifier limits connection lifetime, so that a long-lived mTLS session does not extend the lag indefinitely (see session lifetime and re-validation). |
| Service impersonation / MITM | An adversary attempts to impersonate the MIS or another service. | All endpoints use HTTPS with strict certificate validation, per the TLS requirements. A client authenticates the MIS trust endpoints against its configured initial-trust anchors or pins, per initial trust bootstrap, since the MIS presents no SVID. For mTLS between principals, a peer verifies the presented SVID against its Trust Domain and Trust Bundle, per X.509-SVID validation. |
| Cross-domain trust confusion | A component accepts identities from an unintended Trust Domain. | A verifier determines the Trust Domain from the SPIFFE ID and rejects an SVID whose Trust Domain is not the verifier's own, per X.509-SVID validation. |
| Inadvertent inspection-proxy MITM | An operator-deployed traffic-inspecting proxy intercepts and re-signs Margo mTLS traffic, presenting a substitute certificate to either endpoint. | An operator exempts Margo mTLS endpoints from inspection, per traffic-inspecting proxies. Both endpoints validate peer SVIDs against the Trust Bundle, per X.509-SVID validation, and so reject a substituted certificate. The same section gives deployment guidance for a conduit that requires a control point. |
| Forwarded-identity header injection | In a TLS-offload topology, an attacker injects a forged Client-Cert header to impersonate an authenticated caller at the backend. | The proxy removes or overwrites any Client-Cert or Client-Cert-Chain header on incoming requests, and the backend accepts a forwarded identity only over the authenticated connection from the proxy, per traffic-inspecting proxies. |
| Internal-hop tampering | In a TLS-offload topology, an attacker with access to the connection between the proxy and the backend forges or changes requests, and claims any client identity. MIAF has no application-layer signature, so the backend has no end-to-end check of a request. | The connection between the proxy and the backend is protected against eavesdropping and modification, by means the operator chooses, per traffic-inspecting proxies. From the proxy onwards, the integrity of each request is the operator's responsibility. |
| Replay of early data | An on-path attacker records a TLS 1.3 early-data request and sends it again. Examples are a DELETE that removes a device registration, and an old PUT that restores superseded capability data. | Early data is excluded on every MIAF connection, per the TLS requirements. TLS 1.3 protects data sent after the handshake completes against replay. Replay protection on the connection between a TLS-offloading proxy and the backend is part of the operator's responsibility for that connection (internal-hop row above). |
| Local tampering with cached trust material | An attacker with write access to a device's storage changes the stored trust material. An added anchor in the cached Trust Bundle makes the client accept SVIDs the attacker issues, for example a forged WFM SVID, until the next accepted refresh replaces the bundle. A changed initial-trust anchor, pin, or directly supplied trustBundleUri makes the client accept a bundle from the attacker at the next refresh. A replaced SVID and key make the principal authenticate with an identity that the attacker controls. | A client protects the integrity of its cached trust material at rest, per bundle contents and distribution. Where the device offers no such protection, the operator carries the residual risk and relies on the physical security of the device. |
| Trust endpoint denial of service and refresh stampede | The bundle endpoint is unauthenticated and every principal depends on it. An attacker floods it, or clients that share one spiffe_refresh_hint send their requests at the same time, for example after an outage. | Clients randomize the refresh time and back off on failure, and the MIS rate-limits both trust endpoints, per selecting and refreshing the bundle. A client that cannot refresh keeps its cached bundle, so an outage of the endpoint does not stop validation. |
| Unreliable or manipulated verifier clock | A principal mis-evaluates certificate validity periods because its clock is skewed or unset (a dead RTC battery, no time source at first boot) or because an attacker rewinds it, for example by spoofing an unauthenticated time source on the adversarial network. Rewinding the clock extends the validity window of an expired SVID, defeating the use of expiry as revocation. | SVID validation depends on a trustworthy local time source. A principal uses an authenticated time source where one is available, per certificate validation. The SVID lifetime guidance covers devices with weak clocks, and deployments that cannot assure clock integrity. |
| Handshake identity disclosure on TLS 1.2 fallback | Where an operator enables the optional TLS 1.2 fallback, the mTLS handshake sends the client X.509-SVID in cleartext, so a passive on-path observer can read the peer's SPIFFE ID, and with it its Trust Domain and client relationship. | Default to TLS 1.3, which encrypts the certificate messages, per the TLS requirements. The fallback is disabled by default on both ends and needs explicit operator configuration, so a single misconfigured end cannot downgrade its peers. An operator enables TLS 1.2 only where a deployment requires it, and accepts this passive-disclosure risk. When used, TLS 1.2 follows RFC 9325, per the same requirements. |
WFM Identity Profile Threats
WFM and WFM Client identities inherit the framework threats above. The threats below are specific to this profile.
| Threat | Description | Mitigation |
|---|---|---|
| Wrong-WFM impersonation | A WFM Client connects to a WFM whose SVID is validly issued by the Trust Domain but whose wfm-id is not the one that issued the client, so the client authenticates to the wrong WFM. | The WFM Client verifies the wfm-id in the WFM's SPIFFE path against the wfm-id in its own SVID before authenticating (see Recognition by the WFM Client). |
| Wrong-WFM-Client acceptance | A WFM accepts an SVID whose wfm-id belongs to a different WFM's namespace, treating the bearer as a client of itself. | The WFM verifies the wfm-id in the SPIFFE path against its own namespace before authorizing (see Recognition by the WFM). |
| Unauthorized client within the namespace | A validly issued SVID under a WFM's own namespace (.../wfm/<wfm-id>/client/...) is presented by a party the WFM's operator never authorized; for instance, the MIS issues under the namespace to the wrong principal. | Namespace match alone does not grant access. A WFM admits a caller only if the WFM's accepted-client policy accepts its identity, and the operator constrains the MIS to issue under a WFM's namespace only to that WFM's authorized clients (see Authorization). |
| Stale accepted-client policy | An entry remains in a WFM's accepted-client policy after the relationship is retired, letting a still-valid credential keep accessing the API. | An operator removes wfm-client-id entries promptly per the revocation row of the lifecycle table. The WFM can also deny the request by local policy, surfaced as described in API Requirements and Security, per Authorization. |
| No precise revocation of a compromised WFM | A WFM has no client-side accepted-server allowlist comparable to the WFM's accepted-client policy, so a compromised WFM SVID cannot be revoked precisely: only fleet-wide Trust Bundle rotation or expiry withdraws it, so both the blast radius and the revocation lag are large. | Keep WFM SVIDs short-lived and reissue with the same SPIFFE ID before expiry; use Trust Bundle rotation as the cryptographically enforced revocation path, accepting its fleet-wide scope (see the WFM lifecycle). |
| Compromised see-thru gateway | A see-thru gateway holds the only MIAF identity for itself and for every child device behind it. It reports the existence and capabilities of each child device, receives the desired state for all of them in one state manifest, and routes each deployment by metadata.deviceId. A compromised gateway can report child devices that do not exist, report false capabilities to receive workloads, or deliver a deployment to a device other than the one it names. | Child devices are not principals in this release. The link between the gateway and a child device is outside MIAF, and the deployment secures it by its own means. The WFM Client, not the WFM, enforces metadata.deviceId targeting. A WFM can also constrain which deviceIds a client reports (see API Requirements and Security). A future device identity profile is expected to give child devices their own identities. |
| Non-conformant authentication paths | A WFM exposes an authentication path outside the mTLS model (an unauthenticated onboarding endpoint or an application-layer signature scheme) that an attacker uses to bypass SVID validation. | A WFM authenticates every Management Interface request with mTLS and an X.509-SVID, and rejects requests that do not conform, per API Requirements and Security. |
Security Event Logging
A principal SHOULD log the security events below that have no linked rule. A row with a linked rule points to the page that states the requirement for that event. Each log entry SHOULD carry a timestamp from the principal's clock (see certificate validation).
| Event | Content of the entry |
|---|---|
| Authentication failure | the reason, and the SPIFFE ID of the peer where it presented one |
| Authorization denial | the SPIFFE ID and the policy decision |
| Trust Bundle accepted or rejected | the reason for a rejection |
| Change of the trust anchor set | the anchors added and removed |
| TLS 1.2 negotiated | the peer, per the TLS requirements |
spiffe_sequence regression | per bundle ordering |
| Trust Bundle older than the operator threshold | the time of the last accepted bundle, per selecting and refreshing the bundle |
| Discovery document rejected | the reason: a trustDomain mismatch, or a trustBundleUri on an origin the client does not accept |
| Identity failure of a WFM Client | the cause, per identity failure and deployed workloads |
| Own SVID expired, or its renewal failed | the SPIFFE ID and the notAfter time |
The table maps to the auditable events of IEC 62443-3-3 SR 2.8 and IEC 62443-4-2 CR 2.8. MIAF does not specify log storage, log transport, or retention.
Non-Repudiation
mTLS authenticates a peer for the duration of a connection. It gives no evidence that a third party can verify after the connection ends, so MIAF provides no non-repudiation of requests. A use case that requires non-repudiation needs a signed-message profile, which is not defined in this release.