Poche chiamate.
Qualsiasi piattaforma.

Identity Layer si integra con una superficie minima per progettazione. MicroPython su un microcontrollore, Flutter su Android e Windows, o un PHP bridge inserito nei tuoi endpoint esistenti. Lo stesso protocollo. Le stesse garanzie crittografiche. Quattro chiamate.

Raspberry Pi Pico 2W, PN532 NFC reader, SSD1306 OLED display, NTAG424 DNA card
Boot
Registering
Node exists
Verified
Challenge
Active
Quattro chiamate operative. WiFi, OLED e caricamento della configurazione sono l'infrastruttura del dispositivo, non Identity Layer. L'identità primitiva è IdentityIoT, installato tramite mip.
MicroPython
# Install via mip — no external dependencies
# import mip; mip.install("github:wide/identity-micropython")

from identity_iot import IdentityIoT

# 1. Init — configure node identity
identity = IdentityIoT(
    base_url  = cfg['base_url'],
    node_type = cfg['node_type'],
    tenant_id = cfg['tenant_id'],
    comm_key  = cfg['comm_key'].encode(),
    comm_iv   = cfg['comm_iv'].encode(),
)

# 2. Register — device-bound key, runs once
identity.ensure_registered()

# 3. Authenticate — Ed25519 challenge / verify / JWT
token = identity.authenticate()

# 4. Authenticated request — AES-256-GCM encrypted payload
response = identity.post_encrypted({'request': 'record_sensor_data', 'value': 42})
Componente Modello Ruolo
MCU Raspberry Pi Pico 2W (RP2350) TrustZone, WiFi, archiviazione chiavi device-bound
NFC reader PN532 Interfaccia I2C, legge badge NTAG424 DNA
Display SSD1306 128x64 OLED Sequenza di avvio, stato di verifica
NFC badge NTAG424 DNA (NXP) AES-128 chiavi integrate, non esportabili, dinamiche CMAC
Sono in corso le distribuzioni di riferimento ESP32 e RP2040 per data center e verticali di accesso fisico. Il protocollo e l'SDK sono identici su tutto l'hardware supportato.

I nodi Identity IoT non sono limitati all'accesso NFC. Lo stesso node autenticato può trasportare qualsiasi carico utile del sensore. Tutte le letture vengono trasmesse tramite AES-256-GCM crittografato POST dopo che node ottiene il suo JWT.

Tipo di sensoreHardware tipicoCampo del carico utile
TemperaturaDHT22, DS18B20, BME280temperatura (galleggiante, °C)
UmiditàDHT22, BME280umidità (galleggiante,%)
PressioneBME280, BMP390pressione (galleggiante, hPa)
Movimento PIRHC-SR501movimento (bool)
GPSNEO-6M, L76Xlatitudine, longitudine, altitudine (flottante)
Misurazione dell'energiaPZEM-004T, INA219tensione, corrente, potenza (flottante)
NFC accessoPN532 + NTAG424 DNAbadge_uid, concesso (bool)
JSON (decriptato)
{
  "node_uid"   : "273ec83a-84c8-4967-aafa-0780ab161cc1",
  "tenant_id"  : "0b3cfe4d-fdf7-46c2-bd41-b533da415dd9",
  "node_type"  : "sensor",
  "temperature": 24.3,
  "humidity"   : 58.1,
  "pressure"   : 1013.2,
  "updated_at" : "2026-06-09 11:42:07"
}

Lettura badge. Challenge emessa.
Ed25519 verificato.

Identity Tag è il livello dell'applicazione costruito sopra Identity IoT. Ogni lettura badge attiva un ciclo Ed25519 challenge/response completo rispetto al backend. Nessun segreto memorizzato su reader. Nessuna identità in chiaro su badge. Multi-tenant in base al design.

da Badge a GRANTED in quattro passaggi. Il reader (Pico 2W + PN532) è un Identity IoT node autenticato. badge trasporta un frammento di chiave privata crittografata AES-CBC e un DEK diviso. Il backend lancia una sfida, riceve una firma Ed25519, la verifica e restituisce GRANTED o DENIED. Nessun segreto attraversa il filo nel testo in chiaro. Non esiste alcun database delle credenziali.
Flusso: lettura badge fino alla decisione di accesso
# 1. Reader reads NTAG424 DNA NDEF payload
#    Fields: epk (encrypted private key), df2 (DEK fragment 2), mode (STD|HS)

# 2. DEK reconstruction
dek = df1_from_config XOR df2_from_badge

# 3. Decrypt badge private key
badge_privkey = AES_CBC_decrypt(dek, epk)

# 4. Request challenge from backend
challenge = POST identity_tag/it_request_challenge
#    { node_uid, badge_uid, tenant_id }

# 5. Sign challenge with badge key (Ed25519)
signature = ed25519_sign(badge_privkey, challenge_nonce)

# 6. Verify at backend
result = POST identity_tag/it_verify_badge
#    { challenge_id, signature_b64 }  ->  { granted: true }

# 7. Reader actuates relay (GRANTED) or displays DENIED
ModalitàDescrizioneCaso d'uso
STD Badge funziona su qualsiasi terminale della flotta autorizzata per quel tenant. Accesso agli uffici, punti di ingresso generali.
HS Badge legato crittograficamente a un terminale specifico. La derivazione DEK incorpora un hash della chiave pubblica del terminale. Badge non è valido su nessun altro reader. Sale ad alta sicurezza, rack per data center, armadi per apparecchiature.
Ogni tenant ha uno spazio dei nomi isolato: la propria flotta node, registro badge, albero dei gruppi e tabella dei diritti. Un badge registrato a Tenant A non può essere verificato da un node appartenente a Tenant B. L'isolamento Tenant viene applicato a livello di query del database, non solo tramite la logica dell'applicazione.
Punto finaleMetodoRuolo
identity_tag/it_request_challengePOSTEmetti nonce per la verifica badge
identity_tag/it_verify_badgePOSTVerifica firma Ed25519, restituisci GRANTED/DENIED
identity_tag/it_node_checkinPOSTNode battito cardiaco e JWT aggiornamento
identity_tag/it_register_badgePOST (manager)Scrivi la chiave pubblica e l'autorizzazione badge
identity_tag/it_list_nodesGET (manager)Node stato della flotta per tenant

L'app di provisioning e gestione funziona su Android. Utilizza NFC del dispositivo per scrivere payload badge e si connette al backend tramite canali Identity Layer autenticati.

Dart / Flutter: badge scrivi
// identity_tag package - badge provisioning
final writer = IdentityTagWriter(api: tagApi);

// Generate badge keypair and encrypt private key with split DEK
final payload = await writer.prepareBadgePayload(
  tenantId  : tenant.id,
  mode      : BadgeMode.STD,   // or BadgeMode.HS
  nodeUid   : null,              // required for HS mode
);

// Write NDEF to NTAG424 DNA via flutter_nfc_kit
await writer.writeToTag(payload);

Identità legata al dispositivo.
Quattro chiamate.

Pacchetti locali. Nessun servizio di identità esterna. La chiave privata non lascia mai il dispositivo. Archiviazione sicura tramite flutter_secure_storage e TEE / Secure Enclave quando disponibili. La crittografia del payload è end-to-end tramite ITEMSEncrypter.

identity_package identity_std identity_hs items_crypto items_search items_document_body
Tutti i pacchetti sono locali. Nessuna dipendenza pub.dev dal livello identità. L'SDK è distribuito come parte del pacchetto di licenza.
Dart / Flutter
// 1. Init — JWT identity, silent on subsequent boots
final auth = IdentityAuthServiceStd(ITEMSGlobals.authURI);
await auth.ensureJwt(
  preferredLocale: locale.languageCode,
  utcOffsetMin:    DateTime.now().timeZoneOffset.inMinutes,
);

// 2. Handshake — silent if identity already present on device
final result = await api.mjHandshake(
  identityHash: identityHash,
  publicKey:    publicKey,
);

// 3. Store JWT — session active, no password, no credential database
await _storage.write(key: 'token', value: result['token']);

// 4. Every request — AES-256-GCM payload, end-to-end encrypted
final response = await api.postEncrypted({'request': 'your_request'});
YAML
dependencies:

  # Identity Layer — local packages, no external registry
  identity_package:
    path: packages/identity_package
  identity_std:
    path: packages/identity_std
  identity_hs:
    path: packages/identity_hs
  items_crypto:
    path: packages/items_crypto
PiattaformaStatoArchiviazione sicura
AndroideProduzione, Google Play cancellataArchivio chiavi Android/TEE
FinestreProduzione, Microsoft Store cancellataGestore credenziali di Windows
LinuxProduzionelibsecret
iOS/macOSSulla tabella di marciaSecure Enclave

5KB.
Il tuo stack, invariato.

PHP bridge è un singolo requisito che si trova davanti agli endpoint esistenti. I tuoi percorsi, il tuo database, la tua logica di business. Intatto.. Identity Layer gestisce l'autenticazione e la crittografia del carico utile. Rimuovilo nello stesso modo in cui lo hai aggiunto.

Drop-in, drop-out. Uno require_once e due chiamate di funzione. I tuoi endpoint iniziano a ricevere payload verificati e decrittografati. Nessuna migrazione dello schema. Nessuna modifica alla tabella utente. Nessuna memorizzazione della sessione. Lo stack completo lato server è 225KB.
PHP
// 1. Include the Identity Layer bridge — 5 KB
require_once 'identity/_mj_auth.php';

// 2. Authenticate — JWT verified, identity_hash extracted
//    identity_hash is a 64-char SHA-256 hex — never a user ID
[$identityHash, $tenantId, $claims, $role] =
    mj_authenticate_identity($encoder);

// 3. Every response — AES-256-GCM encrypted, end-to-end
sendEncryptedResponse($encoder, [
    'status' => 'ok',
    'data'   => $yourData,
], ['ts' => time()], 200);
I registri di controllo esistono ma sono crittograficamente inaccessibili. L'accesso richiede un ordine del tribunale convalidato. IL mj_mandate_log punto finale registra il mandato e apre una finestra di esportazione di 72 ore. I registri vengono distrutti dopo la raccolta. L’autorità richiedente ha la responsabilità giuridica.
PHP: mj_mandate_log
// Requires role = admin — never operator
[$userId, $tenantId, $claims, $role] = mj_authenticate($encoder);
mj_require_role($encoder, $claims, 'admin');

// Register mandate — opens 72h export window
// target_identity_hash: 64-char SHA-256, never plaintext identity
// Ciphertext is never stored — metadata only
$connector->executeDatabaseParameterQuery(
    "INSERT INTO audit_log (mandate_number, issuing_country,
     issuing_court, target_identity_hash, export_status)
     VALUES (?, ?, ?, ?, 'PENDING')",
    [$mandateNumber, $issuingCountry, $issuingCourt, $targetHash],
    $db
);
ComponenteTecnologiaNote
DurataPHP 8.xVaniglia, nessuna struttura richiesta
Banca datiMySQL /MariaDBSchema standard, nessuna colonna di credenziali
Cache/effimeroRedisToken di sfida, code di messaggi (TTL < 1 min)
Dimensioni del ponte5KBSingolo file PHP, inseriscilo in qualsiasi stack LAMP
Dimensione dello stack completo225KBIdentità STD + HS + Chiavi + Canale sicuro + IoT + Etichette + Tag
DistribuzioneContenitore/in sede/air-gappedNessuna connettività cloud obbligatoria