Clypeum KLMS REST API Flow

# KLMS REST API Flow

## Authentication
1. **POST** `{iam_base_url}/{iam_realm}/protocol/openid-connect/token`
   - Form body: `grant_type=password&username=&password=&client_id=ccs`
   - mTLS with client cert (PEM: cert + encrypted key from .p12, passphrase entered at runtime)
   - Returns: `{ access_token, refresh_token, expires_in, ... }`
   - Token sent via `x-clylypeum-token` header on subsequent requests

## Background Token Refresh
- Background thread polls every 30s
- When token is near expiry, refreshes via `grant_type=refresh_token&refresh_token=<token>`
- On refresh failure, falls back to full re-authentication
- `SharedCcsClient` uses `Arc<Mutex<CcsClientInner>>` for thread-safe token access

## CCS API Endpoints
Base URL: `{klms.url}` = `https://dev.clypeum.secops.link/ford-fnv4-keyfob/ccs/v1`

### GET /version
- Returns: `HashMap<String, String>` with version info
- Auth: `x-clypeum-token` header

### GET /cryptoContainerTypes
- Returns: `HashMap<String, Value>` keyed by type ID (e.g. `0x001d`, `0x0900`)
- Each entry: `{ Chip, Name, Description }`

### POST /seeds
- Returns: `{ seed: "<hex string>", seedUUID: "<uuid>" }`
- Seed is a hex string, decoded to Vec<u8> on our side
- Used to derive AES key for inner-layer payload encryption

### POST /cryptoContainers
- Form body: `typeID`, `seedUUID`, `productSerial`, `extra` (JSON string)
- **Extra JSON structure** for production container:
  ```json
  {
    "transaction_id": "txn-XXXX",
    "station_id": "station-01",
    "fob": {
      "oef": "B252",
      "uid": "<7-byte chip UID hex>",
      "key_version": "0.0.0"
    },
    "scp03": {
      "host_challenge": "<8 bytes hex, random per session>",
      "card_challenge": "<8 bytes hex from INIT UPDATE response>",
      "sequence_counter": "<3 bytes hex from INIT UPDATE>",
      "card_cryptogram": "<8 bytes hex, computed during SCP03 handshake>"
    },
    "keyBundleType": "dev"
  }
  ```
- Response: `200` with `application/octet-stream` body (container binary)
- Container UUID in header `containeruuid` (lowercase)

### PUT /cryptoContainers/{uuid}
- Report usage/programming status

### DELETE /seeds/{uuid}
- Delete seed

## TLS / mTLS Notes
- Server cert: validated via Clypeum Root CA PEM
- **Known issue**: `danger_accept_invalid_certs(true)` currently used for dev — root CA `Clypeum_Root_CA.pem` returns `BadSignature`. Need correct CA chain.
- Client cert: extracted from .p12 file (same cert as Windows cert store thumbprint in PS scripts)
- Key: encrypted with PBKDF2-HMAC-SHA1 (OpenSSL PKCS#12 default), decrypted at runtime with passphrase
- `reqwest::Identity::from_pem(combined_cert_key_pem)` for mTLS

## Key Files
- `crates/kf-dev-station/src/klms_config.rs`: TOML config parsing
- `crates/kf-dev-station/src/klms_client.rs`: HTTP client, auth, all CCS endpoints
- `crates/kf-dev-station/src/container_parser.rs`: Container binary format parser
- `data/klms-config.toml`: Explicit cert/key/CA paths, IAM settings

id: efb6d30501f34e1f85f3a4549fda6b9c
parent_id: beb251c3b3f9490285e6cb68942a5145
created_time: 2026-08-12T09:59:37.201Z
updated_time: 2026-08-14T16:59:00.391Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1786528777201
user_created_time: 2026-08-12T09:59:37.201Z
user_updated_time: 2026-08-14T16:59:00.391Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
is_locked: 0
extracted_resource_ids: 
type_: 1