Weinig telefoontjes.
Elk platform.

Identity Layer integreert met minimaal oppervlak door ontwerp. MicroPython op een microcontroller, Flutter op Android en Windows, of een PHP bridge die in uw bestaande eindpunten is geplaatst. Hetzelfde protocol. Dezelfde cryptografische garanties. Vier telefoontjes.

Raspberry Pi Pico 2W, PN532 NFC reader, SSD1306 OLED display, NTAG424 DNA card
Boot
Registering
Node exists
Verified
Challenge
Active
Vier operatieve oproepen. WiFi, OLED en het laden van configuraties zijn apparaatinfrastructuur, niet Identity Layer. De identiteitsprimitief is IdentityIoT, geïnstalleerd via 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})
Onderdeel Model Rol
MCU Raspberry Pi Pico 2W (RP2350) TrustZone, WiFi, device-bound sleutelopslag
NFC reader PN532 I2C-interface, leest NTAG424 DNA-badges
Weergave SSD1306 128x64 OLED Opstartvolgorde, verificatiestatus
NFC badge NTAG424 DNA (NXP) AES-128 ingebouwde, niet-exporteerbare sleutels, dynamisch CMAC
ESP32 en RP2040 referentie-implementaties voor datacenters en verticale markten voor fysieke toegang zijn in uitvoering. Het protocol en de SDK zijn identiek voor alle ondersteunde hardware.

Identity IoT-knooppunten zijn niet beperkt tot NFC-toegang. Dezelfde geauthenticeerde node kan elke sensorlading dragen. Alle metingen worden verzonden via AES-256-GCM gecodeerd POST nadat de node zijn JWT heeft verkregen.

SensortypeTypische hardwareLaadvermogenveld
TemperatuurDHT22, DS18B20, BME280temperatuur (vlotter, °C)
VochtigheidDHT22, BME280vochtigheid (float, %)
DrukBME280, BMP390druk (vlotter, hPa)
PIR-bewegingHC-SR501beweging (bool)
GPSNEO-6M, L76Xlat, lon, hoogte (zwevend)
EnergiemetingPZEM-004T, INA219spanning, stroom, vermogen (float)
NFC toegangPN532 + NTAG424 DNAbadge_uid, toegekend (bool)
JSON (gedecodeerd)
{
  "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"
}

Badge lezen. Uitdaging uitgegeven.
Ed25519 geverifieerd.

Identity Tag is de applicatielaag die bovenop Identity IoT is gebouwd. Elke badge-lezing activeert een volledige Ed25519 challenge/response-cyclus tegen de backend. Geen opgeslagen geheimen op de reader. Geen leesbare identiteit op de badge. Multi-tenant door ontwerp.

Badge naar GRANTED in vier stappen. De reader (Pico 2W + PN532) is een geverifieerde Identity IoT node. De badge bevat een met AES-CBC versleuteld privésleutelfragment en een gesplitst DEK. De backend geeft een uitdaging uit, ontvangt een Ed25519-handtekening, verifieert deze en retourneert GRANTED of DENIED. Er gaan geen geheimen door de draad in leesbare tekst. Er bestaat geen referentiedatabase.
Stroom: badge lezen om toegang te krijgen tot de beslissing
# 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
ModusBeschrijvingGebruiksgeval
STD Badge werkt op elke terminal in de geautoriseerde vloot voor die tenant. Toegang tot kantoor, algemene toegangspunten.
HS Badge cryptografisch gebonden aan een specifieke terminal. De DEK-afleiding omvat een hash van de publieke terminalsleutel. Badge is ongeldig op elke andere reader. Hoogbeveiligde ruimtes, datacenterrekken, apparatuurkasten.
Elke tenant heeft een geïsoleerde naamruimte: zijn eigen node-vloot, badge-register, groepsboom en rechtentabel. Een badge geregistreerd bij Tenant A kan niet worden geverifieerd door een node behorend bij Tenant B. Tenant-isolatie wordt afgedwongen op databasequeryniveau, niet alleen via applicatielogica.
EindpuntMethodeRol
identity_tag/it_request_challengePOSTGeef nonce uit voor badge-verificatie
identity_tag/it_verify_badgePOSTVerifieer de handtekening van Ed25519, retourneer GRANTED/DENIED
identity_tag/it_node_checkinPOSTNode hartslag en JWT vernieuwing
identity_tag/it_register_badgePOST (manager)Schrijf de openbare sleutel en het recht badge
identity_tag/it_list_nodesGET (manager)Node vlootstatus voor tenant

De inrichtings- en beheerapp draait op Android. Het gebruikt de NFC van het apparaat om badge-payloads te schrijven en maakt verbinding met de backend via geverifieerde Identity Layer-kanalen.

Dart / Flutter: badge schrijven
// 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);

Apparaatgebonden identiteit.
Vier telefoontjes.

Lokale pakketten. Geen externe identiteitsservice. De privésleutel verlaat het apparaat nooit. Veilige opslag via flutter_secure_storage en TEE / Secure Enclave indien beschikbaar. Payload-encryptie is end-to-end via ITEMSEncrypter.

identity_package identity_std identity_hs items_crypto items_search items_document_body
Alle pakketten zijn lokaal. Geen pub.dev afhankelijkheden van de identiteitslaag. SDK wordt gedistribueerd als onderdeel van het licentiepakket.
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'});
JAML
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
PlatformStatusVeilige opslag
AndroidProductie, Google Play gewistAndroid-sleutelopslag / TEE
RamenProductie, Microsoft Store gewistWindows-referentiebeheer
LinuxProductielibgeheim
iOS/macOSOp routekaartSecure Enclave

5 KB.
Jouw stapel, ongewijzigd.

De PHP bridge is een enkele vereiste die vóór uw bestaande eindpunten wordt geplaatst. Uw routes, uw database, uw bedrijfslogica. Onaangeroerd.. Identity Layer verzorgt de authenticatie en de codering van de payload. Verwijder het op dezelfde manier als waarop u het hebt toegevoegd.

Invallen, uitvallen. Een require_once en twee functieaanroepen. Uw eindpunten ontvangen geverifieerde, gedecodeerde payloads. Geen schemamigratie. Geen wijzigingen in de gebruikerstabel. Geen sessieopslag. De volledige server-side stack is 225 KB.
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);
Er bestaan ​​auditlogboeken, maar deze zijn cryptografisch ontoegankelijk. Voor toegang is een gevalideerd gerechtelijk bevel vereist. De mj_mandate_log eindpunt registreert het mandaat en opent een exportvenster van 72 uur. Logboeken worden na verzameling vernietigd. De verzoekende autoriteit draagt ​​de juridische verantwoordelijkheid.
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
);
OnderdeelTechnologieOpmerkingen
LooptijdPHP 8.xVanille, geen raamwerk vereist
DatabaseMySQL / MariaDBStandaardschema, geen referentiekolommen
Cache / kortstondigRedisUitdagingstokens, berichtenwachtrijen (TTL < 1 min)
Bruggrootte5 KBEén PHP-bestand, plaats het in een willekeurige LAMP-stapel
Volledige stapelgrootte225 KBIdentiteit STD + HS + Sleutels + Beveiligd kanaal + IoT + Labels + Tag
InzetContainer / op locatie / air-gappedGeen verplichte cloudconnectiviteit