diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..3fd2dd4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ +## Summary + + + +## Type of change + +- [ ] feat — new feature +- [ ] fix — bug fix +- [ ] refactor — no behavior change +- [ ] docs — documentation only +- [ ] test — tests only +- [ ] chore — build/CI/config +- [ ] security — security fix + +## Checklist + +- [ ] `python -m unittest discover -s tests -v` passes +- [ ] Related documentation updated in this PR +- [ ] No overclaiming added (claims are verifiable from repository implementation) +- [ ] README updates preserve AZ-02 positioning as a peer Azazel product +- [ ] No changes to `install.sh`, `installer/`, `systemd/`, or runtime behavior without explicit justification below + +## Notes for reviewers + + + +## Related issues + +Closes # diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index a011dae..076d0cc 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -38,3 +38,53 @@ jobs: - name: Run unit tests run: python -m unittest discover -s tests -v + + readme-guard: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate README links and fenced blocks + run: | + python - <<'PY' + import re + from pathlib import Path + import sys + + targets = [Path("README.md"), Path("README_ja.md")] + errors = [] + + for md in targets: + if not md.exists(): + errors.append(f"{md}: file not found") + continue + text = md.read_text(encoding="utf-8") + + # Fence balance check + fence_count = text.count("```") + if fence_count % 2 != 0: + errors.append(f"{md}: unbalanced fenced code blocks (count={fence_count})") + + # Relative markdown/image links check + links = re.findall(r'\]\(([^)]+)\)', text) + for link in links: + if "://" in link or link.startswith("#") or link.startswith("mailto:"): + continue + rel = link.split("#", 1)[0].strip() + if not rel: + continue + p = Path(rel) + if not p.exists(): + errors.append(f"{md}: missing relative path -> {link}") + + if errors: + print("README guard failed:") + for e in errors: + print(f"- {e}") + sys.exit(1) + + print("README guard passed.") + PY diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..11781d3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,71 @@ +# AGENTS.md + +This file defines repository-specific working rules for coding/documentation agents. + +## Scope + +- Repository: `01rabbit/Azazel-Gadget` +- Product: `AZ-02 Azazel-Gadget` +- Positioning: peer product in the Azazel system (not a reduced AZ-01 variant) + +## Core Product Positioning + +When editing documentation, keep this framing: + +- AZ-01 Azazel-Edge: Deterministic Edge SOC/NOC Gateway +- AZ-02 Azazel-Gadget: Personal Tactical Defense Gateway / Cyber Scapegoat Gateway +- AZ-02 stands between protected endpoint and untrusted surrounding network. + +Avoid describing AZ-02 as: + +- VPN replacement +- generic travel router +- endpoint security replacement +- complete attack-prevention system + +## Documentation Guardrails + +- Do not add claims that cannot be verified from repository implementation. +- Preserve explicit claim vs non-claim boundaries. +- Keep top-level README product-facing, precise, and restrained. +- Keep `README.md` and `README_ja.md` structurally aligned. +- Prefer linking existing files; do not add dead links. + +Related policy docs: + +- `docs/INDEX.md` +- `docs/SERIES_POSITIONING_AND_TERMS.md` +- `docs/SECURITY_CLAIM_POLICY.md` + +## Release and Changelog Rules + +- Follow `docs/RELEASE_PROCESS.md`. +- Keep `docs/CHANGELOG.md` updated using Keep a Changelog style. +- Use `docs/RELEASE_NOTES_TEMPLATE.md` for release notes. + +## CI Expectations + +Before release/documentation-sensitive PR merge: + +```bash +python -m unittest discover -s tests -v +``` + +README guard checks must pass: + +- relative links/images valid in `README.md` and `README_ja.md` +- fenced code block balance + +## Change Boundaries + +For documentation tasks: + +- Do not modify runtime behavior, installer behavior, or file naming unless explicitly requested. +- If changing `install.sh`, `installer/`, `systemd/`, include explicit rationale in PR. + +## Preferred PR Checklist + +- Summary of intent and scope +- Evidence for any security-relevant claim +- Test/validation commands and results +- Updated docs map/changelog when externally visible behavior or claims change diff --git a/README.md b/README.md index 8f6d8a6..f27ecab 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ > **Codename:** `TACMOD` +

+ + Release + + + CI Tests + + + Pages + +

+

日本語 @@ -197,7 +209,13 @@ Token auth: Primary entry points: +- [Documentation Index](docs/INDEX.md) +- [Series Positioning and Terms](docs/SERIES_POSITIONING_AND_TERMS.md) +- [Security Claim Policy](docs/SECURITY_CLAIM_POLICY.md) - [Installer Guide](installer/README.md) +- [Release Process](docs/RELEASE_PROCESS.md) +- [Release Notes Template](docs/RELEASE_NOTES_TEMPLATE.md) +- [Changelog](docs/CHANGELOG.md) - [Presentation Assets](docs/presentation/README.md) - [Docs Site Entry](docs/index.html) - [Regression Test Notes](scripts/tests/regression/README.md) diff --git a/README_ja.md b/README_ja.md index 7f9ad54..2ac1811 100644 --- a/README_ja.md +++ b/README_ja.md @@ -1,7 +1,19 @@ -# AZ-02 Azazel-Gadget - Personal Tactical Defense Device +# AZ-02 Azazel-Gadget - パーソナル戦術防御ゲートウェイ > **コードネーム:** `TACMOD` +

+ + Release + + + CI Tests + + + Pages + +

+

日本語 @@ -11,131 +23,126 @@

-Azazel-Gadget は、不審な Wi-Fi 環境向けの携行型防御ゲートウェイです。主対象は Raspberry Pi Zero 2 W / Pi 4 クラスです。 -

Azazel-Gadget logo

- - - - - - + Raspberry Pi + Python + Flask + JavaScript + HTML5 + CSS3

-## コンセプト +Azazel-Gadget は Azazel システムの AZ-02 ポータブル構成であり、低信頼 Wi-Fi・敵対的ローカルセグメント・現場運用向けのパーソナル戦術防御ゲートウェイ / Cyber Scapegoat Gateway です。ユーザー端末と周辺ネットワークの間に立ち、初期ネットワーク挙動を観測し、`portal` / `shield` / `scapegoat` の決定論的モードで露出を制御し、Web UI・TUI・E-paper・(任意)ローカル通知で運用状態を可視化します。 -Azazel-Gadget は、常時携行できる「身代わり防壁」です。 -公共 Wi-Fi のような低信頼ネットワーク環境において、ユーザー端末の前面に立ち、攻撃を直接受け止めることを前提に設計された個人向け戦術デバイスです。 +Azazel-Gadget は VPN ではなく、汎用トラベルルーターでもなく、完全な攻撃防止を約束するものでもありません。 -本ツールは、単に通信を遮断する一般的なセキュリティ製品ではありません。攻撃者の行動原理を前提に、防御面を最小化し、横移動を遮断し、必要に応じて露出を制御できる構造を持ちます。デフォルトは完全防御(Shield)。しかし状況に応じて、観測的防御(Scapegoat)へと態勢を変更することが可能です。 +**対象ユーザー:** セキュリティ研究者、フィールド防御担当者、旅行者、インシデントレスポンダー、レッド/ブルーチーム運用者、および低信頼ネットワークでポータブル防御ゲートウェイを必要とするユーザー。 -攻撃を知らずに守るのではなく、攻撃を知った上で守る。 -Azazel-Gadget は、防御専用機でありながら、戦術的判断を伴う装置です。平時は静かに防御し、異常時には態勢を変える。必要であれば攻撃を引き受け、観測し、時間を稼ぐ。 +## 要件 -それは、日常的に携行できる前線装置です。 -見えないセキュリティではなく、意識的に構えるための盾。 +| 要件 | 内容 | +|---|---| +| ハードウェア | Raspberry Pi Zero 2 W / Raspberry Pi 4 クラス | +| OS | Raspberry Pi OS / Linux | +| ランタイム | Python 3.x、Flask ベースのローカル Web UI | +| ネットワーク | 保護クライアント側 `usb0`、上流側 `wlan0` | +| 任意機能 | E-paper、OpenCanary、Suricata、ntfy、portal viewer | -## ハードウェア実装バリエーション +## クイックスタート -| Azazel-Gadget Portable | Azazel-Gadget Dock | -| --- | --- | -| Raspberry Pi Zero 2 W 実装 ![Azazel-Gadget Portable on Raspberry Pi Zero W](images/Azazel-Gadget_Portable.png) | Raspberry Pi 3/4/4B 実装 ![Azazel-Gadget Shield on Raspberry Pi 4](images/Azazel-Gadget_Shield.png) | +```bash +sudo ./install.sh --all +# 再起動が必要な場合: +sudo ./install.sh --resume +``` -## インターフェース プレビュー +最小確認: -| Web UI | 統合 TUI | -|---|---| -| [![Azazel-Gadget Web UI スクリーンショット](images/WebUI.png)](images/WebUI.png) | [![Azazel-Gadget 統合 TUI スクリーンショット](images/TUI.png)](images/TUI.png) | - -Azazel-Gadget は、能動的なネットワーク防御と運用UI、任意のデコイ機能を一体化したポータブルゲートウェイです。 - -## 主な機能 - -### 1) first-minute 制御プレーン -- 上流接続状態とキャプティブポータルを監視し、`NORMAL`/`DEGRADED`/`CONTAIN` を制御。 -- UI 用スナップショット JSON を生成。 -- ローカル Status API(`:8082`)で `/action/*` と `/details` を提供。 -- Tactics の意思決定ログ出力や ntfy 通知フックを実装。 -- `DECEPTION` 時は、Suricata で OpenCanary 宛攻撃と判定した通信フローに限定して `tc` 遅延を適用(対象限定 Delay-to-Win)。 - -### 2) Control Daemon(Unix socket) -- `/run/azazel/control.sock` でアクション要求を受け付け。 -- シェルスクリプト系アクション、Wi-Fi scan/connect、portal viewer 起動を実行。 -- `watch_snapshot` によるスナップショット配信に対応。 -- パススキーマ関連アクション(`path_schema_status`, `migrate_path_schema`)を提供。 - -### 3) Web UI バックエンド(Flask) -- ダッシュボード HTML、状態 API、状態 SSE。 -- 新旧アクション API、Wi-Fi API、portal viewer API。 -- ntfy ブリッジ SSE(`/api/events/stream`)。 -- ローカル HTTPS 用 CA 証明書メタ情報/配布 API。 -- トークン認証(トークンファイルが存在する場合)。 - -### 4) Portal Viewer(noVNC) -- Chromium + Xvfb + x11vnc + noVNC によるポータル操作支援。 -- WebUI からオンデマンド起動して URL を返却。 -- 実行時 start URL 上書きに対応。 - -### 5) E-paper 連携 -- 起動/終了スプラッシュ表示。 -- キャプティブポータル関連の定期表示更新。 -- Suricata 連動表示更新。 - -### 6) 任意のローカル監視/デコイ -- OpenCanary ユニットと起動ラッパーを同梱。 -- Suricata 稼働状態を WebUI に反映。 -- 軽量 canary ルールは `wlan0` 上の同一LAN端末からの `22/80` スキャン/アクセス試行も検知対象。 -- `--with-ntfy` でローカル ntfy サーバ(`:8081`)を導入可能。 +```bash +sudo systemctl status azazel-mode azazel-first-minute azazel-control-daemon azazel-web --no-pager +``` ## アーキテクチャ概要 -0. `azazel-mode.service` + `azctl` - - 起動時の既定モードとして常に `shield` を適用(起動時は保存モードを無視)。 - - ファイアウォール/sysctl/OpenCanary の適用を単一の実行系に集約。 - - 監査ログと EPD 状態を更新。 -1. `azazel-first-minute.service` - - 状態スナップショット生成と Status API(`:8082`)を提供。 -2. `azazel-control-daemon.service` - - `/run/azazel/control.sock` 経由でアクション実行を仲介。 -3. `azazel-web.service` - - Flask バックエンド(既定 `127.0.0.1:8084`)として状態取得/操作 API を提供。 -4. 任意 `caddy.service`(`--with-webui`) - - `https://:443` で Flask へリバースプロキシ。 -5. 任意 `azazel-portal-viewer.service` - - 既定 `10.55.0.10:6080` の noVNC を必要時起動。 - -## モード - -| モード | 挙動 | EPD サンプル | +```mermaid +flowchart LR + U[Protected Endpoint] --> G[Azazel-Gadget Gateway] + G --> M[Mode Controller] + M --> P[Portal] + M --> S[Shield] + M --> D[Scapegoat] + G --> O[Operator Interfaces] + O --> W[Web UI] + O --> T[TUI] + O --> E[E-paper] + D --> C[OpenCanary / Deception] + G --> A[Audit and State Files] +``` + +## Azazel-Gadget が行うこと + +- ポータブル防御ゲートウェイとして動作する。 +- `portal` / `shield` / `scapegoat` の決定論的モードを提供する。 +- 保護対象 `usb0` クライアントを上流からの inbound と分離する。 +- Web UI・TUI・E-paper による可視性を提供する。 +- 必要に応じて OpenCanary の隔離デコイ公開を行う。 +- 実装されている範囲で Suricata / OpenCanary / ntfy 状態を反映する。 +- 状態とモード変更を運用者レビュー可能な形で記録する。 + +## Security Boundary Summary + +Azazel-Gadget の主張: + +- ローカルファーストな防御ゲートウェイ挙動 +- 運用者が明示選択するモード +- 上流 `wlan0` から保護側 `usb0` クライアントへの inbound 経路がないこと +- 監査可能な状態を伴う決定論的モード切替 +- 保護クライアント側から分離された任意デコイ公開 + +Azazel-Gadget が主張しないこと: + +- あらゆる敵対 Wi-Fi 攻撃への完全防御 +- エンドポイント防御、VPN、企業 NAC の置き換え +- 自律的攻撃応答 +- 不可視・無操作のセキュリティ +- アクティブモードを理解しないままでの安全運用 + +## Operating Modes + +| Mode | 挙動 | EPD サンプル | |---|---|---| -| `portal` | `usb0` クライアント向けのインターネットゲートウェイ動作(`wlan0` 経由NAT)。`wlan0` 側のデコイ公開は OFF。 | ![Portal mode EPD sample](images/portal_composite.png) | -| `shield`(既定) | `usb0` クライアントの外向き通信を維持しつつ、`wlan0` からの inbound を遮断。デコイ公開は OFF。 | ![Shield mode EPD sample](images/shield_composite.png) | -| `scapegoat` | `wlan0` では OpenCanary 許可ポートのみ公開。OpenCanary は隔離 namespace(`az_canary`)で動作し、`usb0` への経路を持たない。 | ![Scapegoat mode EPD sample](images/scapegoat_composite.png) | +| `portal` | 保護対象 `usb0` クライアント向け NAT/ゲートウェイ挙動。デコイ公開は無効。 | ![Portal mode EPD sample](images/portal_composite.png) | +| `shield`(既定) | 既定の防御姿勢。`wlan0` からの inbound を遮断しつつ、保護側の outbound を維持。 | ![Shield mode EPD sample](images/shield_composite.png) | +| `scapegoat` | OpenCanary の許可ポートのみ公開。Canary は `az_canary` ネームスペースで隔離し、保護側と分離。 | ![Scapegoat mode EPD sample](images/scapegoat_composite.png) | 警告表示(モードではない): | 表示 | トリガー | EPD サンプル | |---|---|---| -| `WARNING` | 監視パイプラインがアラート条件を検知した際に表示。 | ![Warning EPD sample](images/warning_composite.png) | +| `WARNING` | 監視パイプラインが警告条件を検知。 | ![Warning EPD sample](images/warning_composite.png) | -## 同梱サービス(systemd) +## ハードウェアバリエーション -| Unit | 役割 | +| Azazel-Gadget Portable | Azazel-Gadget Dock | |---|---| -| `azazel-first-minute.service` | 制御プレーン本体 | -| `azazel-control-daemon.service` | Unix socket アクションデーモン | -| `azazel-web.service` | Flask バックエンド | -| `azazel-portal-viewer.service` | Captive Portal Viewer(noVNC) | -| `usb0-static.service` | `usb0` 固定 IPv4 設定 | -| `azazel-nat.service` | iptables ベース NAT/forward 補助 | -| `azazel-epd.service` | E-paper 起動表示 | -| `azazel-epd-shutdown.service` | E-paper 終了表示 | -| `azazel-epd-portal.service` + `.timer` | ポータル検知表示更新 | -| `suri-epaper.service` | Suricata 連動 E-paper 更新 | -| `opencanary.service` | 任意デコイサービス | +| Raspberry Pi Zero 2 W 実装
![Azazel-Gadget Portable](images/Azazel-Gadget_Portable.png) | Raspberry Pi 3/4/4B 実装
![Azazel-Gadget Shield](images/Azazel-Gadget_Shield.png) | + +## インターフェース + +| Web UI | Unified TUI | +|---|---| +| [![Azazel-Gadget Web UI screenshot](images/WebUI.png)](images/WebUI.png) | [![Azazel-Gadget unified TUI screenshot](images/TUI.png)](images/TUI.png) | + +リポジトリ内の運用インターフェース: + +- Web UI バックエンドとダッシュボード: `azazel_web/` +- 統合 TUI モニタ/メニュー: `py/azazel_gadget/cli_unified.py` +- 互換メニューランチャー: `py/azazel_menu.py` +- 端末ステータス表示: `py/azazel_status.py` +- E-paper 描画/制御: `py/azazel_epd.py`, `py/boot_splash_epd.py` ## インストールオプション @@ -143,83 +150,90 @@ Azazel-Gadget は、能動的なネットワーク防御と運用UI、任意の | オプション | 効果 | |---|---| -| `--with-webui` | Flask venv + Caddy HTTPS を導入 | | `--with-canary` | OpenCanary を導入/有効化 | -| `--with-ntfy` | ローカル ntfy サーバ(`:8081`)導入 | -| `--with-portal-viewer` | noVNC/Chromium 構成を導入 | -| `--with-epd` | Waveshare E-Paper 依存導入(既定 ON) | -| `--all` | 上記オプションを一括有効化 | -| `--resume` | 再起動後の続きから実行 | - -例: - -```bash -sudo ./install.sh --all -# 再起動が必要になった場合 -sudo ./install.sh --resume -``` +| `--with-epd` | Waveshare E-Paper 依存を有効化(既定有効) | +| `--with-webui` | Flask venv + Caddy HTTPS リバースプロキシを導入 | +| `--with-ntfy` | ローカル ntfy サーバと通知連携を導入 | +| `--with-portal-viewer` | noVNC/Chromium Captive Portal Viewer 構成を導入 | +| `--all` | 上記の任意機能を一括有効化 | +| `--resume` | 再起動が必要なネットワーク段の後続処理を再開 | -## Web API 一覧 +## Web API | Endpoint | 内容 | |---|---| -| `GET /` | ダッシュボード | -| `GET /api/state` | 状態 + 監視状態 + portal viewer 状態 | +| `GET /` | ダッシュボード HTML | +| `GET /api/state` | 現在スナップショット | | `GET /api/state/stream` | 状態 SSE | -| `GET /api/events/stream` | ntfy ブリッジ SSE | +| `GET /api/mode` | 現在モード情報 | +| `POST /api/mode` | モード切替(`portal`/`shield`/`scapegoat`) | | `GET /api/portal-viewer` | noVNC 状態/URL | -| `POST /api/portal-viewer/open` | portal viewer 起動/URL返却 | -| `POST /api/action` | 新形式アクション | -| `POST /api/action/` | 旧形式アクション | -| `GET /api/wifi/scan` | Wi-Fi スキャン(既定でトークン不要) | +| `POST /api/portal-viewer/open` | portal viewer 起動/表示 | +| `GET /api/events/stream` | ntfy イベント SSE ブリッジ | +| `POST /api/action` | アクション(v1形式) | +| `POST /api/action/` | アクション(legacy形式) | +| `GET /api/wifi/scan` | Wi-Fi スキャン | | `POST /api/wifi/connect` | Wi-Fi 接続 | | `GET /api/certs/azazel-webui-local-ca/meta` | ローカルCAメタ情報 | | `GET /api/certs/azazel-webui-local-ca.crt` | ローカルCAダウンロード | -| `GET /health` | Web バックエンドヘルス | +| `GET /health` | バックエンドヘルス | 許可アクション: -`refresh`, `reprobe`, `contain`, `release`, `details`, `stage_open`, `disconnect`, `wifi_scan`, `wifi_connect`, `portal_viewer_open`, `shutdown`, `reboot` +`refresh`, `reprobe`, `contain`, `release`, `details`, `stage_open`, `disconnect`, `wifi_scan`, `wifi_connect`, `portal_viewer_open`, `mode_set`, `mode_status`, `mode_get`, `mode_portal`, `mode_shield`, `mode_scapegoat`, `shutdown`, `reboot` トークン認証: -- Header: `X-AZAZEL-TOKEN` / `X-Auth-Token` -- Query: `?token=...` - -## インターフェース -- Web UI: `azazel_web/` -- 統合 TUI(モニタ/メニュー): `py/azazel_gadget/cli_unified.py` -- 互換ランチャー: `py/azazel_menu.py` -- 端末ステータス表示: `py/azazel_status.py` -- E-paper 描画/制御: `py/azazel_epd.py`, `py/boot_splash_epd.py` +- Header: `X-AZAZEL-TOKEN` または `X-Auth-Token` +- Query: `?token=...` -## テスト +## Services (systemd) -- 単体テスト: `tests/` -- 回帰テストスクリプト: `scripts/tests/regression/` -- UIスタックスモーク: `scripts/tests/e2e/run_ui_stack_smoke.sh` +| Unit | 役割 | +|---|---| +| `azazel-mode.service` | 起動時モード適用 (`azctl mode apply-default`) | +| `azazel-first-minute.service` | 制御プレーン本体 | +| `azazel-control-daemon.service` | Unix socket アクションデーモン | +| `azazel-web.service` | Flask API/UI バックエンド | +| `azazel-portal-viewer.service` | Captive Portal Viewer(noVNC) | +| `usb0-static.service` | `usb0` に固定IPv4を設定 | +| `azazel-nat.service` | NAT/forward 補助 | +| `azazel-epd.service` | E-paper 起動表示 | +| `azazel-epd-refresh.service` + `azazel-epd-refresh.timer` | E-paper 定期モード/状態更新 | +| `azazel-epd-shutdown.service` | E-paper 終了処理 | +| `azazel-epd-portal.service` + `azazel-epd-portal.timer` | Captive Portal 定期検知 | +| `suri-epaper.service` | Suricata 連動 E-paper 更新 | +| `opencanary.service` | OpenCanary サービス | +| `opencanary@.service` | 専用ネットワーク名前空間での OpenCanary | -## パス互換性 +## Documentation Map -2系統の命名をサポートしています。 -- 標準: `azazel-gadget`(`/etc/azazel-gadget`, `/run/azazel-gadget`, `~/.azazel-gadget`) -- 旧名: `azazel-zero`(`/etc/azazel-zero`, `/run/azazel-zero`, `~/.azazel-zero`) +主要エントリ: -スキーマ補助/移行は `py/azazel_gadget/path_schema.py` で提供しています。 -旧パス互換は `2026-12-31` までを目安に維持予定です。 +- [Documentation Index](docs/INDEX.md) +- [Series Positioning and Terms](docs/SERIES_POSITIONING_AND_TERMS.md) +- [Security Claim Policy](docs/SECURITY_CLAIM_POLICY.md) +- [Installer Guide](installer/README.md) +- [Release Process](docs/RELEASE_PROCESS.md) +- [Release Notes Template](docs/RELEASE_NOTES_TEMPLATE.md) +- [Changelog](docs/CHANGELOG.md) +- [Presentation Assets](docs/presentation/README.md) +- [Docs Site Entry](docs/index.html) +- [Regression Test Notes](scripts/tests/regression/README.md) -## ディレクトリ構成(主要) +## Repository Layout -| Path | 内容 | +| Path | 役割 | |---|---| -| `py/azazel_gadget/` | 制御、センサー、Tactics、パススキーマ | -| `py/azazel_control/` | 制御デーモン、Wi-Fi処理、アクションスクリプト | -| `azazel_web/` | Flask バックエンド + フロント | +| `py/azazel_gadget/` | コントローラ、センサー、tactics engine、path schema | +| `py/azazel_control/` | control daemon、Wi-Fi ハンドラ、アクションスクリプト | +| `azazel_web/` | Flask バックエンドとダッシュボード資産 | | `systemd/` | service/timer ユニット | -| `installer/` | 段階的インストーラ | -| `configs/` | 既定設定テンプレート | -| `scripts/` | 実行補助とテストスクリプト | -| `docs/` | 開発/アーカイブ文書 + プレゼン資料(`docs/presentation/`) | +| `installer/` | 段階的インストーラ構成 | +| `configs/` | 既定ランタイム設定 | +| `scripts/` | ランタイム補助とテストスクリプト | +| `docs/` | ドキュメントとプレゼン資産 | +| `images/` | README/プレゼン用画像資産 | ## ライセンス -リポジトリ内の `LICENSE`(存在する場合)を参照してください。 +このリポジトリには現在、トップレベル `LICENSE` ファイルはありません。 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..dfbfb47 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,45 @@ +# Changelog + +This file follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +## [Unreleased] + +### Added +- Series-level documentation baseline: + - `docs/INDEX.md` (cross-series entry map) + - `docs/SERIES_POSITIONING_AND_TERMS.md` (AZ-01/AZ-02 terminology and boundaries) + - `docs/SECURITY_CLAIM_POLICY.md` (documentation claim policy) + - `docs/RELEASE_NOTES_TEMPLATE.md` (Azazel-Edge style release note template) + +### Changed +- `README.md` and `README_ja.md` documentation maps now include series/index/policy/release-template entry points. + +## [0.1.0] - 2026-05-16 + +### Added +- Product-facing README restructuring for AZ-02 positioning: + - deterministic top-level structure for reviewers/operators + - explicit security boundary claims/non-claims section + - architecture overview and operating mode guarantees +- CI unit-test workflow (`.github/workflows/ci-tests.yml`) running: + - `python -m unittest discover -s tests -v` + - dependency bootstrap for `PyYAML` +- README guard checks in CI: + - local relative link/image path validation for `README.md` and `README_ja.md` + - fenced code-block balance validation +- Release process baseline documentation: + - `docs/RELEASE_PROCESS.md` +- Pull request quality gate template: + - `.github/PULL_REQUEST_TEMPLATE.md` +- Japanese README alignment with English top-level structure and claim boundaries. + +### Changed +- README top section now includes operational badges: + - latest release + - CI tests workflow + - GitHub Pages workflow +- Documentation map updated to include release/changelog entry points. +- License wording in README clarified to reflect repository reality (no top-level `LICENSE` file currently present). + +### Security +- Documentation and review process now explicitly enforce non-overclaiming language and verifiable security claims only. diff --git a/docs/INDEX.md b/docs/INDEX.md new file mode 100644 index 0000000..6045b86 --- /dev/null +++ b/docs/INDEX.md @@ -0,0 +1,29 @@ +# Azazel Documentation Index + +This index provides series-level entry points and repository-local documentation map for Azazel-Gadget (AZ-02). + +## Azazel Series Positioning + +- AZ-01 Azazel-Edge: Deterministic Edge SOC/NOC Gateway + Reference repository: [01rabbit/Azazel-Edge](https://github.com/01rabbit/Azazel-Edge) +- AZ-02 Azazel-Gadget: Personal Tactical Defense Gateway (this repository) + Repository: [01rabbit/Azazel-Gadget](https://github.com/01rabbit/Azazel-Gadget) + +## Primary Documents (This Repository) + +| Path | Audience | Purpose | +|---|---|---| +| [../README.md](../README.md) | Reviewer / Operator | Product overview (English) | +| [../README_ja.md](../README_ja.md) | Reviewer / Operator | Product overview (Japanese) | +| [CHANGELOG.md](CHANGELOG.md) | Reviewer / Developer | Release trace and documentation history | +| [RELEASE_PROCESS.md](RELEASE_PROCESS.md) | Maintainer | Tag/release workflow and quality gates | +| [RELEASE_NOTES_TEMPLATE.md](RELEASE_NOTES_TEMPLATE.md) | Maintainer | Standard release note template (Azazel-Edge style) | +| [SERIES_POSITIONING_AND_TERMS.md](SERIES_POSITIONING_AND_TERMS.md) | Reviewer / Developer | Series vocabulary and AZ-01/AZ-02 boundary definitions | +| [SECURITY_CLAIM_POLICY.md](SECURITY_CLAIM_POLICY.md) | Reviewer / Developer | Allowed claim boundaries and evidence requirements | +| [presentation/README.md](presentation/README.md) | Presenter | Presentation assets map | + +## Operational Notes + +- Product claims must be implementation-verifiable. +- AZ-02 is a peer Azazel product, not a reduced variant of AZ-01. +- Do not describe AZ-02 as a VPN replacement or complete attack-prevention system. diff --git a/docs/RELEASE_NOTES_TEMPLATE.md b/docs/RELEASE_NOTES_TEMPLATE.md new file mode 100644 index 0000000..707984f --- /dev/null +++ b/docs/RELEASE_NOTES_TEMPLATE.md @@ -0,0 +1,30 @@ +# Azazel-Gadget vX.Y.Z Release Notes + +## Theme + +One-paragraph summary of release intent (hardening, clarity, feature line, etc.). + +## Highlights + +### Runtime or behavior changes +- Item + +### Documentation and operational clarity +- Item + +### CI/quality updates +- Item + +## Scope boundaries + +- What this release changes +- What this release does not claim +- Any unchanged safety boundaries + +## Validation checklist (release candidate) + +```bash +python -m unittest discover -s tests -v +``` + +Add any release-specific validation commands below when applicable. diff --git a/docs/RELEASE_PROCESS.md b/docs/RELEASE_PROCESS.md new file mode 100644 index 0000000..ac4e10f --- /dev/null +++ b/docs/RELEASE_PROCESS.md @@ -0,0 +1,67 @@ +# Release Process + +This document defines the standard release flow for Azazel-Gadget, aligned with Azazel-Edge operational style. + +## Versioning and tags + +- Tag format: `vMAJOR.MINOR.PATCH` (example: `v0.1.0`) +- Release title format: `Azazel-Gadget vX.Y.Z` +- Default release type: non-draft, non-prerelease unless explicitly required + +## Required pre-release checks + +Before creating a tag/release: + +```bash +python -m unittest discover -s tests -v +``` + +CI expectations: + +- `CI Tests` workflow is green on target commit +- README guard checks are green: + - local link/image path validity in `README.md` and `README_ja.md` + - fenced code block balance + +## Release note style + +Use the same structure style as Azazel-Edge release notes: + +1. `Theme` +2. `Highlights` +3. `Scope boundaries` +4. `Validation checklist (release candidate)` + +Claims in release notes must be: + +- repository-verifiable +- bounded (no autonomous/complete protection claims) +- explicit about what changed vs what did not + +## Release sequence + +1. Confirm working tree is clean. +2. Confirm tests/CI pass. +3. Update docs as needed: + - `docs/CHANGELOG.md` + - release notes document (for example `docs/RELEASE_NOTES_vX.Y.Z.md`) +4. Create and push tag: + +```bash +git tag vX.Y.Z +git push origin vX.Y.Z +``` + +5. Create GitHub release: + +```bash +gh release create vX.Y.Z \ + --title "Azazel-Gadget vX.Y.Z" \ + --notes-file docs/RELEASE_NOTES_vX.Y.Z.md +``` + +## Post-release checks + +- Verify release URL and artifact visibility on GitHub. +- Verify README badges reflect new release tag. +- Ensure changelog and release notes remain consistent. diff --git a/docs/SECURITY_CLAIM_POLICY.md b/docs/SECURITY_CLAIM_POLICY.md new file mode 100644 index 0000000..1eb3263 --- /dev/null +++ b/docs/SECURITY_CLAIM_POLICY.md @@ -0,0 +1,33 @@ +# Security Claim Policy + +This policy defines acceptable claim boundaries for Azazel-Gadget documentation and release notes. + +## Claim Rules + +Any security claim must be: + +- implementation-verifiable from this repository +- written in bounded language (what is and is not claimed) +- consistent with current mode semantics and network boundaries + +## Allowed Claim Patterns + +- deterministic mode switching with visible operator state +- no inbound path from upstream `wlan0` to protected `usb0` clients +- optional isolated deception exposure via OpenCanary in scapegoat mode +- local-first operation without cloud dependency requirements + +## Disallowed Claim Patterns + +- complete protection against all hostile network attacks +- replacement for endpoint security, VPN, NAC, or enterprise SOC tooling +- autonomous offensive response capability +- invisible/zero-interaction security guarantees + +## Evidence Expectations + +When adding or modifying security claims, PRs should include: + +1. Repository evidence references (service units, scripts, mode manager behavior, API endpoints). +2. Updated claim/non-claim text in `README.md` and `README_ja.md` when relevant. +3. Changelog entry for externally visible claim boundary changes. diff --git a/docs/SERIES_POSITIONING_AND_TERMS.md b/docs/SERIES_POSITIONING_AND_TERMS.md new file mode 100644 index 0000000..2e5355d --- /dev/null +++ b/docs/SERIES_POSITIONING_AND_TERMS.md @@ -0,0 +1,41 @@ +# Azazel Series Positioning and Terms + +This document standardizes cross-repository wording for Azazel series documentation. + +## Product Relationship + +- AZ-01 Azazel-Edge + Deterministic Edge SOC/NOC Gateway for constrained, temporary, and high-risk local networks. +- AZ-02 Azazel-Gadget + Personal Tactical Defense Gateway for untrusted Wi-Fi, hostile local segments, and field use. + +Both are peer products in the same Azazel system. + +## Canonical Terms + +- `Deterministic mode`: explicit mode behavior selected by operator or deterministic policy logic. +- `Cyber Scapegoat Gateway`: gateway posture that receives first contact and exposes controlled surfaces to buy operator decision time. +- `Protected side`: AZ-02 `usb0` client-facing segment. +- `Upstream side`: AZ-02 `wlan0` network-facing segment. +- `Operating modes`: `portal`, `shield`, `scapegoat` (plus warning display state, which is not a mode). + +## Required Positioning Language for AZ-02 + +Documentation should describe AZ-02 as: + +- portable personal tactical defense gateway +- cyber scapegoat gateway +- standing between endpoint and surrounding untrusted network +- deterministic, operator-visible control surface + +Documentation must avoid describing AZ-02 as: + +- generic travel router +- VPN replacement +- endpoint security replacement +- autonomous offensive security platform + +## Cross-Repository Linking Guidance + +- When mentioning AZ-01 design lineage, link to Azazel-Edge repository root or the specific public document. +- Keep AZ-02 claims bounded to this repository implementation.