- tools/make_deploy_bundles.py: PMS7003·Zero2W 디스플레이 노드 번들 생성 반영(폐쇄망 동봉) - tools/harden_pi.sh: 하드닝 스크립트 갱신 - docs/superpowers: 노드 센서 통합·스모크 파일럿·대시보드 다크 설계/계획 문서 - docs/claude-config: IoT 납품·검증 스킬/룰 참조본 - review/: 프로젝트 리뷰·UI v2 목업
43 lines
2.2 KiB
Markdown
43 lines
2.2 KiB
Markdown
# IoT Delivery Verification Rules
|
|
|
|
> Companion to [build-deployment.md](./build-deployment.md) (air-gapped bundles) and the
|
|
> `iot-airgap-delivery` skill (full workflow). These are always-on behavioral rules.
|
|
|
|
## Derived-key discipline (CRITICAL)
|
|
|
|
- Master secret (API_KEY) lives only on the server config + build machine secrets dir.
|
|
Leaf devices get HMAC-derived keys only (`hash_hmac('sha256', '<label>', API_KEY)`).
|
|
- Servers recompute derived keys per request — never ask "where is the derived key stored
|
|
on the server"; print it: `php -r 'require "config.php"; echo hash_hmac(...);'`
|
|
- Never regenerate the master secret casually — it orphans every deployed node. Bundle
|
|
generators must reuse the existing secret file; verify the key prefix after every run.
|
|
- Before any commit: real secret files (`config_local.py`, `config.local.php`,
|
|
`secrets.h`) must be gitignored AND absent from history
|
|
(`git log --all --full-history -- <path>`). Leak → rotate.
|
|
|
|
## Deploy bundle discipline
|
|
|
|
- Source tree is truth. Never hand-edit generated `deploy/` files — edit source, re-run
|
|
the generator, redeploy.
|
|
- After every source change that ships: regenerate bundles, then state which bundle goes
|
|
where (server upload vs Pi copy + `systemctl restart <service>`).
|
|
|
|
## HTTP client discipline (shared-hosting targets)
|
|
|
|
- Every Python `requests` call to a shared-hosting server MUST send a custom User-Agent
|
|
(WAFs commonly 403 the default `python-requests/x.y` while curl passes).
|
|
- Debugging 403: first decide WHO rejected (JSON body = app/key; HTML = WAF/Apache),
|
|
then follow the ladder in the `iot-airgap-delivery` skill. Don't guess — curl it.
|
|
|
|
## Render verification (device displays)
|
|
|
|
- Never ship display-render changes verified only by reading code. Render synthetic
|
|
worst-case frames to PNG at exact panel resolution, inspect them visually, show the
|
|
user previews (SendUserFile), THEN deploy.
|
|
|
|
## Poll-heavy endpoint rules
|
|
|
|
- Time-window SQL must ride an index (composite indexes need their leading column in
|
|
WHERE — loop per-entity if needed). Cap result sets with LIMIT. Whole handler in
|
|
try/catch with generic error JSON. File-based per-IP rate limit that fails OPEN
|
|
(monitoring must not die from its own throttle). JSON responses evolve additively only.
|