電話はほとんどありません。
あらゆるプラットフォーム。

Identity Layer は、設計により最小限の表面と統合されています。 マイクロコントローラーでは MicroPython、Android および Windows では Flutter、 または、PHP bridge を既存のエンドポイントにドロップします。 同じプロトコル。同じ暗号化保証。電話は4回。

Raspberry Pi Pico 2W, PN532 NFC reader, SSD1306 OLED display, NTAG424 DNA card
Boot
Registering
Node exists
Verified
Challenge
Active
工作員の呼び出しは4回。 WiFi、OLED、構成の読み込みはデバイスのインフラストラクチャです。 Identity Layer ではありません。 ID プリミティブは IdentityIoT、 経由でインストールされました 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})
成分 モデル 役割
MCU Raspberry Pi Pico 2W (RP2350) TrustZone、WiFi、device-bound キー ストレージ
NFC reader PN532 I2C インターフェイス、NTAG424 DNA バッジを読み取ります
画面 SSD1306 128x64 OLED ブートシーケンス、検証ステータス
NFC badge NTAG424 DNA (NXP) AES-128 オンボード、エクスポート不可キー、動的 CMAC
データセンターおよび物理アクセス分野向けの ESP32 および RP2040 のリファレンス展開が進行中です。 プロトコルと SDK は、サポートされているすべてのハードウェアで同一です。

Identity IoT ノードは NFC アクセスに限定されません。同じ認証された node は、任意のセンサー ペイロードを運ぶことができます。 すべての読み取り値は、node が JWT を取得した後、AES-256-GCM 暗号化された POST を介して送信されます。

センサーの種類代表的なハードウェアペイロードフィールド
温度DHT22、DS18B20、BME280温度 (フロート、°C)
湿度DHT22、BME280湿度 (浮動小数点、%)
プレッシャーBME280、BMP390圧力 (フロート、hPa)
PIRモーションHC-SR501モーション (ブール値)
GPSNEO-6M、L76X緯度、経度、高度 (float)
エネルギー計測PZEM-004T、INA219電圧、電流、電力 (float)
NFC アクセスPN532 + NTAG424 DNAbadd_uid、付与 (ブール値)
JSON (復号化された)
{
  "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 を読みました。チャレンジが発行されました。
Ed25519 が確認されました。

Identity Tag は、Identity IoT の上に構築されたアプリケーション層です。 各 badge 読み取りにより、バックエンドに対して完全な Ed25519 challenge/response サイクルがトリガーされます。 reader には秘密は保存されません。 badge には平文の ID がありません。マルチtenant設計。

Badge から GRANTED までの 4 つのステップ。 reader (Pico 2W + PN532) は、認証済みの Identity IoT node です。 badge は、AES-CBC で暗号化された秘密キーのフラグメントと分割された DEK を伝送します。 バックエンドはチャレンジを発行し、Ed25519 署名を受信して​​検証し、GRANTED または DENIED を返します。 秘密が平文で通信を通過することはありません。資格情報データベースが存在しません。
フロー: badge 読み取りからアクセスの決定
# 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
モード説明使用事例
STD Badge は、その tenant に対して認可されたフリート内の任意の端末で動作します。 オフィスへのアクセス、一般的な入り口。
HS Badge 暗号的に特定の端末にバインドされます。 DEK 派生には、端末公開キーの hash が組み込まれています。 Badge は、他の reader では無効です。 高セキュリティの部屋、データセンターラック、機器キャビネット。
各 tenant には、独立した名前空間 (独自の node フリート、badge レジストリ、グループ ツリー、資格テーブル) があります。 Tenant A に登録された badge は、Tenant B に属する node では検証できません。 Tenant 分離は、アプリケーション ロジックだけではなく、データベース クエリ レベルで適用されます。
終点方法役割
identity_tag/it_request_challengePOSTbadge 検証のために nonce を発行します
identity_tag/it_verify_badgePOSTEd25519 署名を検証し、GRANTED/DENIED を返します
identity_tag/it_node_checkinPOSTNode ハートビートと JWT リフレッシュ
identity_tag/it_register_badgePOST (manager)badge 公開キーと資格を書き込みます
identity_tag/it_list_nodesGET (manager)tenant の Node フリート ステータス

プロビジョニングおよび管理アプリは Android 上で実行されます。デバイスの NFC を使用して badge ペイロードを書き込みます そして、認証された Identity Layer チャネルを介してバックエンドに接続します。

Dart / Flutter: badge 書き込み
// 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);

デバイスにバインドされた ID。
電話は4回。

ローカルパッケージ。外部 ID サービスはありません。秘密キーがデバイスの外に出ることはありません。 安全なストレージを介して flutter_secure_storage 利用可能な場合は、TEE / Secure Enclave。 ペイロード暗号化はエンドツーエンドで行われます。 ITEMSEncrypter

identity_package identity_std identity_hs items_crypto items_search items_document_body
すべてのパッケージはローカルです。 ID レイヤーに pub.dev の依存関係はありません。 SDK は、ライセンス パッケージの一部として配布されます。
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
プラットフォーム状態安全なストレージ
アンドロイド本番環境、Google Play クリアAndroid キーストア / TEE
本番環境、Microsoft Store クリアWindows 資格情報マネージャー
Linux生産libsecret
iOS / macOSロードマップ上Secure Enclave

5KB。
スタックは変更されません。

PHP bridge は、既存のエンドポイントの前に位置する単一のリクエストです。 ルート、データベース、ビジネス ロジック。手付かずの.. Identity Layer は認証とペイロード暗号化を処理します。 追加したときと同じ方法で削除します。

ドロップイン、ドロップアウト。 1つ require_once そして 2 つの関数呼び出し。エンドポイントは、検証され、復号化されたペイロードの受信を開始します。 スキーマの移行はありません。ユーザーテーブルは変更されません。セッションストレージはありません。 完全なサーバー側スタックは次のとおりです。 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);
監査ログは存在しますが、暗号化によりアクセスできません。 アクセスするには有効な裁判所命令が必要です。 の mj_mandate_log エンドポイント 委任を登録し、72 時間の輸出ウィンドウを開きます。 ログは収集後に破棄されます。要求当局は法的責任を負います。
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
);
成分テクノロジー注意事項
ランタイムPHP 8.xバニラ、フレームワークは不要
データベースMySQL / マリアDB標準スキーマ、資格情報列なし
キャッシュ/一時的Redisチャレンジ トークン、メッセージ キュー (TTL < 1 分)
ブリッジサイズ5KB単一の PHP ファイル、任意の LAMP スタックにドロップ
フルスタックサイズ225KBID STD + HS + キー + セキュア チャネル + IoT + ラベル + タグ
導入コンテナ / オンプレミス / air-gapped必須のクラウド接続はありません