Få samtal.
Vilken plattform som helst.

Identity Layer integreras med minimal yta genom design. MicroPython på en mikrokontroller, Flutter på Android och Windows, eller en PHP bridge släpptes till dina befintliga slutpunkter. Samma protokoll. Samma kryptografiska garantier. Fyra samtal.

Raspberry Pi Pico 2W, PN532 NFC reader, SSD1306 OLED display, NTAG424 DNA card
Boot
Registering
Node exists
Verified
Challenge
Active
Fyra operativa samtal. WiFi, OLED och konfigurationsladdning är enhetsinfrastruktur, inte Identity Layer. Identiteten primitiva är IdentityIoT, installeras 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})
Komponent Modell Roll
MCU Raspberry Pi Pico 2W (RP2350) TrustZone, WiFi, device-bound nyckellagring
NFC reader PN532 I2C-gränssnitt, läser NTAG424 DNA märken
Visa SSD1306 128x64 OLED Startsekvens, verifieringsstatus
NFC badge NTAG424 DNA (NXP) AES-128 ombord, icke-exporterbara nycklar, dynamiska CMAC
ESP32 och RP2040 referensdistributioner för datacenter och vertikaler för fysisk åtkomst pågår. Protokollet och SDK är identiska för all hårdvara som stöds.

Identity IoT noder är inte begränsade till NFC åtkomst. Samma autentiserade node kan bära vilken sensor som helst. Alla avläsningar sänds via AES-256-GCM krypterad POST efter att node erhållit sin JWT.

SensortypTypisk hårdvaraNyttolastfält
TemperaturDHT22, DS18B20, BME280temperatur (flyta, °C)
FuktighetDHT22, BME280luftfuktighet (flyta, %)
TryckBME280, BMP390tryck (flyta, hPa)
PIR-rörelseHC-SR501rörelse (bool)
GPSNEO-6M, L76Xlat, lon, höjd (flyta)
EnergimätningPZEM-004T, INA219spänning, ström, effekt (float)
NFC åtkomstPN532 + NTAG424 DNAbadge_uid, beviljad (bool)
JSON (dekrypterad)
{
  "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 läst. Utmaning utfärdad.
Ed25519 verifierad.

Identity Tag är applikationslagret som är byggt ovanpå Identity IoT. Varje badge läsning utlöser en hel Ed25519 challenge/response cykel mot backend. Inga lagrade hemligheter på reader. Ingen klartextidentitet på badge. Multi-tenant genom design.

Badge till GRANTED i fyra steg. reader (Pico 2W + PN532) är en autentiserad Identity IoT node. badge bär ett AES-CBC-krypterat privat nyckelfragment och en delad DEK. Backend utfärdar en utmaning, tar emot en Ed25519-signatur, verifierar den och returnerar GRANTED eller DENIED. Inga hemligheter går igenom tråden i klartext. Det finns ingen referensdatabas.
Flöde: badge läs för åtkomstbeslut
# 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
LägeBeskrivningAnvändningsfall
STD Badge fungerar på vilken terminal som helst i den auktoriserade flottan för den tenant. Tillgång till kontor, allmänna ingångspunkter.
HS Badge kryptografiskt bunden till en specifik terminal. DEK härledningen innehåller en hash av terminalens publika nyckel. Badge är ogiltigt på alla andra reader. Högsäkerhetsrum, datacenterställ, utrustningsskåp.
Varje tenant har ett isolerat namnområde: sin egen node flotta, badge register, gruppträd och rättighetstabell. En badge registrerad på Tenant A kan inte verifieras av en node som tillhör Tenant B. Tenant-isolering upprätthålls på databasfrågenivå, inte enbart via applikationslogik.
SlutpunktMetodRoll
identity_tag/it_request_challengePOSTProblem nonce för badge verifiering
identity_tag/it_verify_badgePOSTVerifiera Ed25519 signatur, returnera GRANTED/DENIED
identity_tag/it_node_checkinPOSTNode hjärtslag och JWT uppdatering
identity_tag/it_register_badgePOST (manager)Skriv badge offentlig nyckel och behörighet
identity_tag/it_list_nodesGET (manager)Node flotta status för tenant

Provisionerings- och hanteringsappen körs på Android. Den använder enhetens NFC för att skriva badge nyttolaster och ansluter till backend över autentiserade Identity Layer-kanaler.

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

Enhetsbunden identitet.
Fyra samtal.

Lokala paket. Ingen extern identitetstjänst. Den privata nyckeln lämnar aldrig enheten. Säker förvaring via flutter_secure_storage och TEE / Secure Enclave när de är tillgängliga. Nyttolastkryptering sker från ända till ända via ITEMSEncrypter.

identity_package identity_std identity_hs items_crypto items_search items_document_body
Alla paket är lokala. Inga pub.dev-beroenden på identitetslagret. SDK distribueras som en del av licenspaketet.
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
PlattformStatusSäker förvaring
AndroidProduktion, Google Play rensadAndroid Keystore / TEE
WindowsProduktion, Microsoft Store rensadWindows Credential Manager
LinuxProduktionlibsecret
iOS / macOSPå färdplanenSecure Enclave

5 KB.
Din stack, oförändrad.

PHP bridge är ett enda krav som sitter framför dina befintliga slutpunkter. Dina rutter, din databas, din affärslogik. Orörd.. Identity Layer hanterar autentisering och nyttolastkryptering. Ta bort den på samma sätt som du lade till den.

Drop-in, drop-out. En require_once och två funktionsanrop. Dina slutpunkter börjar ta emot verifierade, dekrypterade nyttolaster. Ingen schemamigrering. Inga ändringar i användartabellen. Ingen sessionslagring. Den kompletta stacken på serversidan är 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);
Granskningsloggar finns men är kryptografiskt otillgängliga. Tillgång kräver ett validerat domstolsbeslut. De mj_mandate_log slutpunkt registrerar fullmakten och öppnar ett 72-timmars exportfönster. Loggar förstörs efter insamling. Den begärande myndigheten bär det juridiska ansvaret.
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
);
KomponentTeknologiAnteckningar
KörningPHP 8.xVanilj, ingen ram krävs
DatabasMySQL / MariaDBStandardschema, inga autentiseringskolumner
Cache / efemärRedisUtmaningstokens, meddelandeköer (TTL < 1 min)
Brostorlek5 KBEnstaka PHP-fil, släpp i valfri LAMP-stack
Full stack storlek225 KBIdentitet STD + HS + Nycklar + Secure Channel + IoT + Etiketter + Tag
SpridningBehållare / på plats / air-gappedIngen obligatorisk molnanslutning