# TPM-Based Security Provider **Task**: AZ-182_tpm_security_provider **Name**: TPM Security Provider **Description**: Introduce SecurityProvider abstraction with TPM detection and FAPI integration, wrapping existing security logic in LegacySecurityProvider for backward compatibility **Complexity**: 5 points **Dependencies**: None **Component**: 02 Security **Tracker**: AZ-182 **Epic**: AZ-181 ## Problem The loader's security code (key derivation, encryption, hardware fingerprinting) is hardcoded for the binary-split scheme. On fused Jetson Orin Nano devices with fTPM, this scheme is unnecessary — full-disk encryption protects data at rest, and the fleet update system (AZ-185) handles encrypted artifact delivery with per-artifact keys. However, the loader still needs a clean abstraction to: 1. Detect whether it's running on a TPM-equipped device or a legacy environment 2. Provide TPM seal/unseal capability as infrastructure for defense-in-depth (sealed credentials, future key wrapping) 3. Preserve the legacy code path for non-TPM deployments ## Outcome - Loader detects TPM availability at startup and selects the appropriate security provider - SecurityProvider abstraction cleanly separates TPM and legacy code paths - TpmSecurityProvider establishes FAPI connection and provides seal/unseal operations - LegacySecurityProvider wraps existing security.pyx unchanged - Foundation in place for fTPM-sealed credentials (future) and per-artifact key decryption integration ## Scope ### Included - SecurityProvider abstraction (ABC) with TpmSecurityProvider and LegacySecurityProvider - Runtime TPM detection (/dev/tpm0 + SECURITY_PROVIDER env var override) - tpm2-pytss FAPI integration: connect, create_seal, unseal - LegacySecurityProvider wrapping existing security.pyx (encrypt, decrypt, key derivation) - Auto-detection and provider selection at startup with logging - Docker compose device mounts for /dev/tpm0 and /dev/tpmrm0 - Dockerfile changes: install tpm2-tss native library + tpm2-pytss - Tests using TPM simulator (swtpm) ### Excluded - Resource download/upload changes (handled by AZ-185 Update Manager with per-artifact keys) - Docker unlock flow changes (handled by AZ-185 Update Manager) - fTPM provisioning pipeline (manufacturing-time, separate from code) - Remote attestation via EK certificates - fTPM-sealed device credentials (future enhancement, not v1) - Changes to the Azaion admin API server ## Acceptance Criteria **AC-1: SecurityProvider auto-detection** Given a Jetson device with provisioned fTPM and /dev/tpm0 accessible When the loader starts Then TpmSecurityProvider is selected and logged **AC-2: TPM seal/unseal round-trip** Given TpmSecurityProvider is active When data is sealed via FAPI create_seal and later unsealed Then the unsealed data matches the original **AC-3: Legacy path unchanged** Given no TPM is available (/dev/tpm0 absent) When the loader starts and processes resource requests Then LegacySecurityProvider is selected and all behavior is identical to the current scheme **AC-4: Env var override** Given SECURITY_PROVIDER=legacy is set When the loader starts on a device with /dev/tpm0 present Then LegacySecurityProvider is selected regardless of TPM availability **AC-5: Graceful fallback** Given /dev/tpm0 exists but FAPI connection fails When the loader starts Then it falls back to LegacySecurityProvider with a warning log **AC-6: Docker container TPM access** Given docker-compose.yml with /dev/tpm0 and /dev/tpmrm0 device mounts When the loader container starts on a fused Jetson Then TpmSecurityProvider can connect to fTPM via FAPI ## Non-Functional Requirements **Performance** - TPM seal/unseal latency must be under 500ms per operation **Compatibility** - Must work on ARM64 Jetson Orin Nano with JetPack 6.1+ - Must work inside Docker containers with --device mounts - tpm2-pytss must be compatible with Python 3.11 and Cython compilation **Reliability** - Graceful fallback to LegacySecurityProvider on any TPM initialization failure - No crash on /dev/tpm0 absence — clean detection and fallback ## Unit Tests | AC Ref | What to Test | Required Outcome | |--------|-------------|-----------------| | AC-1 | SecurityProvider factory with /dev/tpm0 mock present | TpmSecurityProvider selected | | AC-2 | FAPI create_seal + unseal via swtpm | Data matches round-trip | | AC-3 | SecurityProvider factory without /dev/tpm0 | LegacySecurityProvider selected | | AC-4 | SECURITY_PROVIDER=legacy env var with /dev/tpm0 present | LegacySecurityProvider selected | | AC-5 | /dev/tpm0 exists but FAPI raises exception | LegacySecurityProvider selected, warning logged | ## Blackbox Tests | AC Ref | Initial Data/Conditions | What to Test | Expected Behavior | NFR References | |--------|------------------------|-------------|-------------------|----------------| | AC-3 | No TPM device available | POST /load/{filename} (split resource) | Existing binary-split behavior, all current tests pass | Compatibility | | AC-6 | TPM simulator in Docker | Container starts with device mounts | FAPI connects, seal/unseal works | Compatibility | ## Constraints - tpm2-pytss requires tpm2-tss >= 2.4.0 native library in the Docker image - Tests require swtpm (software TPM simulator) — must be added to test infrastructure - fTPM provisioning is out of scope — this task assumes a provisioned TPM exists - PCR-based policy binding intentionally not used (known persistence issues on Orin Nano) ## Risks & Mitigation **Risk 1: fTPM FAPI stability on Jetson Orin Nano** - *Risk*: FAPI seal/unseal may have undocumented issues on Orin Nano (similar to PCR/NV persistence bugs) - *Mitigation*: Design intentionally avoids PCR policies and NV indexes; uses SRK hierarchy only. Hardware validation required before production deployment. **Risk 2: swtpm test fidelity** - *Risk*: Software TPM simulator may not reproduce all fTPM behaviors - *Mitigation*: Integration tests on actual Jetson hardware as part of acceptance testing (outside CI). **Risk 3: tpm2-tss native library in Docker image** - *Risk*: tpm2-tss may not be available in python:3.11-slim base image; ARM64 build may need compilation - *Mitigation*: Add tpm2-tss to Dockerfile build step; verify ARM64 compatibility early.