Skip to content

jungamer-64/RustCMS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

591 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 CMS バックエンド

CI Docker Build Docker Release Security Audit

高性能で本番運用に耐えるコンテンツ管理システム(CMS)API。Rust と Axum を用いて構築され、大規模トラフィックを想定した機能を備えています。

🚀 主な特徴

パフォーマンスとスケーラビリティ

  • 高性能アーキテクチャ: Rust と Axum による最大性能を意識した実装
  • データベース接続プーリング: PostgreSQL 向けの最適化された接続管理
  • Redis キャッシュ: レスポンスタイム向上のための多層キャッシュ戦略
  • レートリミット: 悪用防止のためのインテリジェントなレート制御
  • ロードバランサ対応: ステートレス設計で水平スケールが容易

セキュリティ

  • JWT 認証 (EdDSA / Ed25519): 非対称鍵署名による JWT トークン認証。Ed25519 による署名で、秘密鍵漏洩時のリスクを軽減(Phase 5.7)。
    • 鍵の自動生成: 初回起動時に Ed25519 鍵ペアを自動生成(./secrets/ed25519.key
    • HS256 フォールバック: EdDSA 鍵がない場合、従来の HS256 にフォールバック
    • 鍵ファイルのパーミッション: 秘密鍵は自動的に chmod 600 に設定(Unix系)
  • Biscuit トークン (Capability ベース): Ed25519 署名付き権限デリゲーション。柔軟なポリシー表現とファクト駆動の権限管理を提供。
  • ロールベースアクセス制御: 詳細な権限管理
  • 入力検証: リクエストの包括的なバリデーション
  • CORS 設定: クロスオリジン制御の設定が可能
  • SQL インジェクション防止: パラメタライズドクエリと型安全性
  • リフレッシュトークンローテーション: セッションごとに refresh_version をインクリメントし使い捨て化、再利用攻撃を軽減。
  • API キー認証 (X-API-Key): サーバ生成の長期利用向けキー。Argon2 での秘密ハッシュ + SHA-256 (base64url) 決定的 lookup hash により O(1) 検索が可能。キー管理エンドポイントはユーザ認証 (Biscuit) 後に作成/一覧/失効操作を提供。

モニタリングと可観測性

  • Prometheus メトリクス: 包括的なメトリクス収集
  • 構造化ログ: tracing による詳細ログ出力
  • ヘルスチェック: エンドポイントおよびサービスのヘルス監視
  • パフォーマンストラッキング: リクエスト時間などの分析

開発者体験

  • OpenAPI ドキュメント: 自動生成される Swagger UI
  • 型安全性: Rust の型システムによる実行時エラーの低減
  • モダンな非同期処理: Tokio ベースの async ランタイム
  • Docker サポート: 本番対応のコンテナ化

🚩 Feature Flags(機能フラグ)

RustCMS は柔軟な feature flags で機能を選択的に有効化できます。

基本 Features

Feature 説明 デフォルト
auth Biscuit 認証、Argon2 パスワードハッシュ
database PostgreSQL + Diesel ORM
cache Redis + Moka インメモリキャッシュ
search Tantivy 全文検索エンジン
email SMTP メール送信 (lettre)
compression HTTP レスポンス圧縮
monitoring Prometheus メトリクス

構造再編 Features (Phase 1-7 完了) ✅

✅ Phase 7 完了: RustCMS はドメイン駆動設計(DDD)への移行が完了しました(2025年10月19日)

Feature 対応 Phase 説明 状態
restructure_domain Phase 1-2 Value Objects + Entities デフォルト
restructure_application Phase 3 Use Cases + Repositories ✅ 完了
restructure_presentation Phase 4 新ハンドラー (/api/v2) ✅ 完了
full_restructure Phase 5-7 完全DDD構造 + Legacy削除 完了

主要成果:

  • ✅ 25ファイル削除 (~300KB legacy code removed)
  • ✅ 392 tests passing (100%)
  • ✅ 新DDD構造のみでビルド可能
  • ✅ レガシーコード完全削除完了

ビルド例

# デフォルト構成(全機能有効)
cargo build --release

# 最小構成(認証とDB のみ)
cargo build --release --no-default-features --features "auth,database"

# 開発用(monitoring 有効)
cargo build --features "development"

# DDD構造(Phase 7完了後はデフォルトで有効)
cargo build --release

# Full restructure(すべての新構造を有効化)
cargo build --features "full_restructure"

詳細は以下を参照:


API レスポンス統一 & コントラクトテスト

全エンドポイントは共通構造 ApiResponse<T> を返します。

// 成功
{
  "success": true,
  "data": { /* 任意のペイロード */ },
  "message": null,
  "error": null,
  "validation_errors": null
}

// バリデーションエラー
{
  "success": false,
  "data": null,
  "message": null,
  "error": "validation failed",
  "validation_errors": [
    {"field": "title", "message": "must not be empty"}
  ]
}

簡易な成功パスはハンドラで ApiOk(payload) を返すだけです。従来の ok/err/ok_message ヘルパは非推奨 (将来削除)。

スナップショット (contract) テスト

tests/contract_snapshots.rs で代表的な 4 パターン (成功 / 成功+message / エラー / バリデーションエラー) を insta で固定化しています。破壊的変更があると CI で差分が検出されます。

追加で /health エンドポイント形状を監視する 統合スナップショット (tests/integration_health_snapshot.rs) を導入しています。これは本物のサービス初期化に依存せず、決定的なダミー HealthStatus を生成しタイムスタンプを <redacted> にマスクすることでインフラ非依存 & 変動値排除を実現しています。

拡張方針:

  • 他エンドポイントを追加する際も「実サービス呼び出しを避けた合成データ or 最小スタブ」を返すテストハーネスを用意し、insta::assert_json_snapshot!ApiResponse 形状 (特に data 部) を固定化。
  • 不安定なフィールド (時刻 / ランダム ID / 並列で順序変動) は事前に書き換え or 削除してください。

実行例:

# 既存スナップショットを含む全チェック
cargo insta test

# health のみ (普通の cargo test 経由)
cargo test snapshot_health_endpoint -- --exact

新規追加 → 差分確認 → 受け入れのフローは従来と同じです。

更新フロー:

# 変更検証
cargo insta test

# 差分を確認 (対話)
cargo insta review

# 全て受け入れる (非推奨: 内容確認後に実行)
cargo insta accept

重い鍵生成テストの高速化

FAST_KEY_TESTS=1 を設定すると高速版圧縮テストのみ実行し、フルバックアップ/圧縮テストをスキップする CI マトリクス構成が可能です。 例: GitHub Actions でのステップ:

- name: Fast tests
  run: FAST_KEY_TESTS=1 cargo test --all --no-fail-fast

長時間走る完全テストは nightly ジョブに分離する運用を推奨します。

📊 アーキテクチャ

インフラ構成

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   ロードバランサー │    │     Redis       │    │   PostgreSQL    │
│     (Nginx)     │◄──►│     キャッシュ     │    │    データベース    │
└─────────────────┘    └─────────────────┘    └─────────────────┘
                 │                       ▲                       ▲
                 ▼                       │                       │
┌─────────────────┐              │                       │
│   CMS バックエンド  │              │                       │
│   (Rust/Axum)   │──────────────┼───────────────────────┘
│                 │              │
│  ┌─────────────┐│              │
│  │レートリミッター││──────────────┘
│  └─────────────┘│
│  ┌─────────────┐│
│  │   認証       ││
│  └─────────────┘│
│  ┌─────────────┐│
│  │  メトリクス   ││
│  └─────────────┘│
└─────────────────┘

DDD構造(Phase 7完了)✅

Phase 7完了により、完全なDomain-Driven Designアーキテクチャに移行しました:

┌─────────────────────────────────────────────────────────┐
│                    Presentation Layer                    │
│  (API Handlers /api/v2/*, Middleware, OpenAPI)          │
└────────────────────────┬────────────────────────────────┘
                         │
┌────────────────────────▼────────────────────────────────┐
│                   Application Layer                      │
│  ├─ Use Cases (CreatePost, RegisterUser, ...)           │
│  ├─ DTOs (Request/Response objects)                     │
│  ├─ Queries (CQRS - ListUsersQuery, SearchPostsQuery)  │
│  └─ Ports (Repository traits, Service interfaces)      │
└────────────────────────┬────────────────────────────────┘
                         │
┌────────────────────────▼────────────────────────────────┐
│                     Domain Layer                         │
│  ├─ Entities (User, Post, Comment, Tag, Category)      │
│  ├─ Value Objects (UserId, Email, Slug, Title, ...)    │
│  ├─ Domain Services (PostPublishingService, ...)       │
│  ├─ Domain Events (UserRegistered, PostPublished, ...)│
│  └─ Business Logic (Validation, Invariants)            │
└────────────────────────┬────────────────────────────────┘
                         │
┌────────────────────────▼────────────────────────────────┐
│                 Infrastructure Layer                     │
│  ├─ Repository Implementations (Diesel/PostgreSQL)      │
│  ├─ Unit of Work (Transaction management)               │
│  ├─ External Services (Cache, Search, Email)           │
│  └─ Event Bus (Background listeners)                   │
└─────────────────────────────────────────────────────────┘

主要成果(Phase 1-7):

  • 19個の Value Objects - 型安全な検証済み値型
  • 5個の Entities - ビジネスロジック集約(User, Post, Comment, Tag, Category)
  • 10個の Use Cases - アプリケーションロジック分離
  • 5個の Repository Ports + 3個の実装 - インフラ抽象化
  • 20個の Domain Events - イベント駆動アーキテクチャ
  • Unit of Work パターン - トランザクション管理
  • CQRS実装 - クエリとコマンドの分離
  • レガシーコード完全削除 - 25ファイル削除、~300KB削減

テストカバレッジ: 392 tests passing (100%) ✅

詳細は以下を参照:


## 🔐 認証(Biscuit トークンによる統一認証)

本システムは **Biscuit トークン** による認証を採用しています。

- **標準ヘッダ**: `Authorization: Bearer <biscuit_token>`
- **互換スキーム**: `Authorization: Biscuit <biscuit_token>`

公開/保護はルータ構成で管理します。

- **公開エンドポイント(認証不要)**: `/api/v1/auth/register`, `/api/v1/auth/login`, `/api/v1/auth/refresh`, `/api/v1/health/**`, `/api/docs/**`, `/api/v1/metrics`
- **保護エンドポイント(Biscuit認証必須)**: `/api/v1/posts/**`, `/api/v1/users/**`, `/api/v1/api-keys/**`, `/api/v1/auth/logout`, `/api/v1/auth/profile`

保護ルートには認証ミドルウェアが適用され、ハンドラは `Extension<crate::auth::AuthContext>` で検証済みユーザ情報を利用できます。

### 認証の仕組み

1. **ログイン**: `/api/v1/auth/login` で認証情報を送信し、Biscuit トークン(access/refresh)を取得
2. **アクセス**: 保護エンドポイントへのリクエスト時に `Authorization` ヘッダーで Biscuit トークンを送信
3. **検証**: サーバー側で Biscuit トークンの署名検証、有効期限チェック、セッション確認を実施
4. **認可**: ユーザーのロールと権限に基づいてアクセス制御を実行

### API キー認証(Biscuit ベース統合)

長期的なマシン間通信には API キー認証も利用可能です:

- **ヘッダー**: `X-API-Key: ak_<your_api_key>`
- API キーは Argon2 ハッシュで保護され、独立したレート制限を持ちます
- **重要**: API キー認証も内部的には Biscuit ベースの `AuthContext` に変換され、統一的なセキュリティモデルで処理されます
- API キーの発行・管理は Biscuit 認証が必要な `/api/v1/api-keys` エンドポイントで行います

**統一認証アーキテクチャ**:

- 全ての認証メカニズム(Biscuit トークン、API キー)は内部的に同じ `AuthContext` に収束
- ロールベースアクセス制御(RBAC)が一貫して適用
- 詳細は [docs/BISCUIT_UNIFIED_AUTH.md](docs/BISCUIT_UNIFIED_AUTH.md) を参照

```bash
bash scripts/deprecation-auto-guidance.sh

Phase 4 削除 PR ドラフト生成 (ゼロ確認後)

bash scripts/generate_phase4_pr.sh

Grafana ダッシュボード例: monitoring/grafana/auth_unification_dashboard.json をインポート。

CI アーティファクト: Deprecated Scan

ci.ymldeprecated-scan ジョブは scripts/deprecation-scan.sh --src-only を実行し以下をアップロードします:

  • deprecation_counts.csv
  • deprecation_counts.json

*.json はダウンロード後グラフ化や履歴比較に利用できます。--src-only によりテスト/ドキュメント由来の許容参照を除外し、実稼働コードの残存状況のみを追跡します。

将来的にゼロ到達後は --strict を有効化し回帰を CI 失敗に昇格させることを推奨します。

Auth Unification Verification (デュアル + 除去プレビュー)

統一認証レスポンスの両構成(フラット互換あり/なし)を検証するヘルパースクリプト:

./scripts/verify-auth-unification.sh

内部で以下を実行します:

  • フラット互換フィールド無効構成 (--no-default-features + 必要最小 features) 全テスト

補助スキャン (任意 CI informational ジョブ例):

./scripts/deprecation-scan.sh | tee deprecation_scan.txt

生成された一覧をアーティファクト化し、実際に残すべき参照 (テスト or docs) 以外が残っていないかを確認してください。

Phase4 直前チェック:

./scripts/phase4-removal-plan.sh

出力が空 (または docs/ / CHANGELOG のみ) になれば最終削除 PR を作成可能です。

有効化すると以下が有効になります:

将来のメジャーリリースでこの feature とフラットフィールドは削除予定です。新規実装は response.tokens.* を参照してください。

🧭 将来の Breaking (予告 / 3.0.0 計画)

次期メジャー (3.0.0) では以下を削除予定です:

  1. フラットフィールド: access_token, refresh_token, biscuit_token, expires_in, session_id, token

移行ガイド (要約):

  • すべての直接参照を response.tokens.* へ置換 (例: response.access_tokenresponse.tokens.access_token)
  • token (access_token エイリアス) を除去
  • OpenAPI 生成キャッシュをクリアし SDK 再生成

詳細: docs/AUTH_MIGRATION_V2.md の Phase 4 セクションおよび CHANGELOG.md の Planned を参照。

�🛠️ クイックスタート

前提条件

  • Rust 1.75 以上
  • PostgreSQL 13 以上
  • Redis 6 以上
  • Docker(任意)

ローカル開発

  1. リポジトリをクローンします
git clone <repository-url>
cd Rust-CMS  # 任意のフォルダ名
  1. 環境の設定

設定は config/default.toml を基点に環境変数で上書きできます。最低限の例:

cp .env.example .env   # (存在する場合)
# set DATABASE_URL=postgres://user:pass@localhost:5432/cms_db
  1. EdDSA 鍵の設定 (Phase 5.7)

JWT 認証には Ed25519 鍵ペアが必要です。初回起動時に自動生成されます:

# 鍵は ./secrets/ed25519.key に自動保存されます(chmod 600)
# 手動生成も可能:
mkdir -p secrets
# アプリケーション起動時に自動的に生成されます

セキュリティ上の注意:

  • ./secrets/ ディレクトリは .gitignore に含まれています
  • 秘密鍵のパーミッションは自動的に 600 に設定されます(Unix系)
  • 本番環境では、鍵を安全な場所(HSM、Azure Key Vault等)に保管することを推奨
  1. (任意)外部サービスを起動
docker compose up -d postgres redis  # Redis / search を使わないなら省略可
  1. マイグレーション(Diesel を使用する場合、feature database 有効時)
cargo run --bin cms-migrate  # 実装されている簡易マイグレーションバイナリ
  1. サーバ起動
cargo run --bin cms-server

外部サービスを最小にしたビルド例:

cargo build --no-default-features --features "dev-tools,auth,database"
cargo run --no-default-features --features "dev-tools,auth,database" --bin cms-server

補助バイナリ:

  • cms-admin : 管理・運用用 CLI(ユーザ作成など)
  • cms-migrate: DB マイグレーション実行

開発支援バイナリ (dev-tools feature が必要):

  • dev-tools, admin_server, run_docs など(Cargo.toml の [[bin]] セクション参照)

Developer 補助ツール:

  • gen_biscuit_keys : Biscuit トークン用の鍵ペアを生成するユーティリティ。生成した鍵は標準出力へ base64 で出力されます。ファイルや .env へ書き込むオプションもあり、安全に保存することを推奨します。
    • バージョン管理 (--versioned) で biscuit_private_v<N>.b64 / biscuit_public_v<N>.b64 を連番保存し、--latest-alias で常に最新を biscuit_private.b64 / biscuit_public.b64 として同期。
    • manifest.json に最新バージョン番号と fingerprint (SHA-256) を記録。
    • --prune <N> で最新 N バージョンのみ保持、古いものを自動削除。
    • --list で存在するバージョン列挙。
    • バックアップ系: --backup (上書き前に .bak.<unix_ts> へ退避), --max-backups N, --backup-compress (gzip 圧縮 & 元削除), --backup-dir DIR
    • 出力モード: --format stdout|files|env|both (未指定時は従来: 指定ターゲットのみ)。

使い方(簡易):

# stdout に出力のみ
cargo run --bin gen_biscuit_keys

# 鍵ファイルを書き出す(ディレクトリ: keys)
cargo run --bin gen_biscuit_keys -- --format files --out-dir keys

# .env に追記(デフォルト: .env)
cargo run --bin gen_biscuit_keys -- --format env --env-file .env

# 両方に出力して既存を上書き(強制)
cargo run --bin gen_biscuit_keys -- --format both --out-dir keys --env-file .env --force

# 既存をバックアップしてから上書き(バックアップは .bak.<unix_ts>)
cargo run --bin gen_biscuit_keys -- --format files --out-dir keys --backup --force

# バックアップを作成して最新2個だけ保持する
cargo run --bin gen_biscuit_keys -- --format files --out-dir keys --backup --max-backups 2 --force

# バックアップを作成して gzip 圧縮(元ファイルは削除され .gz が残る)
cargo run --bin gen_biscuit_keys -- --format files --out-dir keys --backup --backup-compress --force

# バージョン付きで 3 個だけ保持し manifest 更新、最新 alias も更新
cargo run --bin gen_biscuit_keys -- --format files --out-dir keys --versioned --latest-alias --prune 3 --force

# 既存バージョン列挙
cargo run --bin gen_biscuit_keys -- --out-dir keys --list

セキュリティ注意点:

  • 生成された秘密鍵は厳重に管理してください。パスワード管理ツールや本番では Doppler / Vault 等のシークレットストアを利用してください。
  • リポジトリやコミットに鍵を含めないでください。.env をコミットしない(.gitignore に含める)か、環境シークレット管理を用いてください。
  • バージョン運用時は古い秘密鍵が不要になったタイミングで安全に破棄 (安全な削除/秘匿ストレージ除外) してください。

API キー認証の概要

項目 内容
ヘッダ X-API-Key: ak_<ランダム>
保存方式 Argon2 ハッシュ (秘密) + ルックアップ用 SHA-256(base64url)
失効 Revoke (DB で削除 / expired_at 設定)
パーミッション 文字列配列 (OpenAPI 拡張で列挙)
所有者検証 Revoke / List は作成ユーザのみ
セキュリティ 生キーは一度しか返さない (クライアント安全保管必須)

API キーは長期自動処理 (CI / バッチ / 外部統合) 用。ユーザ認証後に管理エンドポイントで発行し、生キーはそのレスポンス以外では再取得不可。DB では 復号不能 (Argon2) かつ検索高速化のための決定的 lookup_hash (衝突極小) を持ちます。

レガシー行バックフィル

初期段階で lookup_hash 空の行が存在する場合、ミドルウェアは検証成功時にその行へハッシュを後書きし徐々に移行します。運用 CLI (backfill) により一括同定・失効も可能です。

backfill_api_key_lookup バイナリ:

cargo run --features "database,auth" --bin backfill_api_key_lookup

オプション:

フラグ 説明
--expire 対象レガシーキーの expires_at を即時に設定して失効させる
--dry-run 書き込みを行わずスキャン結果のみ表示 (レポートは常に JSON)
--pretty 整形 JSON で出力

出力例:

{
  "scanned": 2,
  "legacy_missing_lookup": 2,
  "expired_marked": 0,
  "rows": [
    {"id":"...","name":"ci-bot","user_id":"...","created_at":"2025-09-04T08:10:22Z"},
    {"id":"...","name":"legacy-agent","user_id":"...","created_at":"2025-09-03T11:44:55Z"}
  ],
  "expire_mode": false,
  "dry_run": true
}

推奨運用フロー:

  1. --dry-run --pretty で影響範囲を確認
  2. 問題なければ --expire を付与して失効 (再発行を促す)
  3. メトリクス / ログでアクセス失敗が急増しないか監視

注意: raw API キーは保存していないためこのツールで再計算はできません (完全な後付け再構築は不可能)。

レート制限 (失敗回数ベース: In-Memory / Redis)

60 秒ウィンドウで同一 lookup hash に紐づく認証失敗 (not_found / hash_mismatch / malformed / expired など) が 10 回 を超えると 429 (Too Many Requests) を返し短期ブルートフォースを緩和します。

バックエンド:

backend 指定 特徴
In-Memory (デフォルト) API_KEY_FAIL_BACKEND=memory または未設定 ライト・単一プロセス向け。高速、プロセス間共有なし。
Redis API_KEY_FAIL_BACKEND=redis (要 feature cache) 分散 / 水平スケール対応。各失敗は Redis INCR + EXPIRE (固定ウィンドウ擬似) でカウント。

Redis バックエンド時の注意:

  1. REDIS_URL が必須。
  2. TTL はウィンドウ秒で EXPIRE。閾値超過判定は INCR 後の値が threshold を超えたかで実施。
  3. tracked_len メトリクスは 15 秒キャッシュされた SCAN 結果。大量キー環境ではオーバーヘッド低減のため頻度を抑制。
  4. キープレフィックスは API_KEY_FAIL_REDIS_PREFIX (デフォルト rk:) で変更可能。衝突回避のためサービス毎に prefix 設定推奨。

���功時にはそのキーの失敗カウンタを即座に削除し (in-memory: map remove / redis: DEL) 正常利用を阻害しません。

環境変数 (未設定時はデフォルト):

変数 デフォルト 説明
API_KEY_FAIL_WINDOW_SECS 60 固定ウィンドウ秒数
API_KEY_FAIL_THRESHOLD 10 ウィンドウ内の許容失敗回数 (超過で 429)
API_KEY_FAIL_MAX_TRACKED 5000 (memory) 失敗カウンタを保持する lookup_hash の最大件数 (超過時は古いエントリを削除)
API_KEY_FAIL_DISABLE false true/1 でレート制限ロジックを無効化 (計測は一部継続)
API_KEY_FAIL_BACKEND memory memory / redis を選択 (redis 利用には feature cache + REDIS_URL)
API_KEY_FAIL_REDIS_PREFIX rk: Redis backend で使用するキー prefix (衝突回避用)

容量制御挙動: 追跡件数が最大の 90% を超えた時点でウィンドウ外の古いエントリを opportunistic に掃除し、なお超過する場合は最も古いエントリを 1 件強制削除します。

✅ 統一レスポンス仕様 (Unified API Response Layer)

すべての成功レスポンスは ApiResponse<T> へ正規化され、ハンドラでは ApiOk(value) を返すだけで以下 JSON 形状になります:

{
  "success": true,
  "data": { /* value */ },
  "message": null,
  "error": null,
  "validation_errors": null
}

バリデーション / ドメインエラー時は:

{
  "success": false,
  "data": null,
  "message": null,
  "error": "Invalid input",
  "validation_errors": [
    {"field": "title", "message": "must not be empty"}
  ]
}

利用パターン

目的 ハンドラ戻り値例 備考
通常成功 ApiOk(entity) entitySerialize
作成 (201) (StatusCode::CREATED, ApiOk(created)) タプルで任意ステータス
ページング ApiOk(Paginated<T>) 内部 data にそのまま格納
メッセージのみ ApiOk(json!({"message":"Done"})) シンプルテキストラップ不要

廃止予定 API

項目 状態 代替
IntoApiOk トレイト deprecated ApiOk(...)
直接 ok(value) ヘルパ 移行段階 ApiOk(value)

実装メモ (開発者向け)

  1. ApiOk<T>IntoResponse 実装を持ち ApiResponse::success(T) を包む。
  2. エラー (AppError) は IntoResponse 実装内で同じ ApiResponse 形状へ統一。
  3. OpenAPI では ApiResponse<serde_json::Value> + ApiResponseExample をスキーマ提供。
  4. バリデーション詳細は validation_errors 配列 (省略時非表示)。

将来: IntoApiOk は段階的に削除予定。コードベース内に存在する場合は PR で置換してください。

メトリクス (主要抜粋)

名前 ラベル 説明
http_requests_total method, path 全リクエスト数
http_requests_success_total status_class 2xx 成功数
http_requests_client_error_total 4xx 数
http_requests_server_error_total 5xx 数
database_queries_total model, op DB クエリ回数
api_key_auth_attempts_total API キー認証試行
api_key_auth_success_total API キー成功
api_key_auth_failure_total reason API キー失敗 (missing_header / malformed / not_found / hash_mismatch / expired / rate_limited / invalid_header_encoding)
rate_limit_violations_total scope (他レートリミット用)

Prometheus 例 (簡易):

api_key_auth_attempts_total 42
api_key_auth_failure_total{reason="not_found"} 7
api_key_auth_success_total 35

ダッシュボードでは (success / attempts) 比率や reason 別失敗をウォッチし、異常増加 (例: not_found 連続増) 時にアラート設定することを推奨します。

サンプル Alert ルール: docs/alerts/prometheus_rules_example.yml に API キー関連のスパイク検出・成功率低下・期限切れ利用・rate_limited 連発検知の例を用意しています。環境のトラフィック特性に合わせて閾値を調整してください。

関連メトリクス (monitoring feature 有効時):

メトリクス 説明
api_key_rate_limit_window_seconds 現在のウィンドウ秒数
api_key_rate_limit_threshold 閾値 (失敗許容回数)
api_key_rate_limit_max_tracked memory backend の最大トラック件数
api_key_rate_limit_tracked_keys 現在追跡中のキー件数 (redis backend は SCAN キャッシュ)
api_key_rate_limit_enabled 有効=1 / 無効=0
api_key_rate_limit_max_tracked 最大追跡キー数
api_key_rate_limit_tracked_keys 現在追跡中キー数 (動的)
api_key_rate_limit_enabled 1=有効 / 0=無効 (API_KEY_FAIL_DISABLE 反映)

デフォルト起動バイナリは cms-serverCargo.tomldefault-run 設定に依存)。

Docker デプロイ

# すべてのサービスをビルドして起動
docker-compose up -d

# ログ確認
docker-compose logs -f cms-backend

# バックエンドをスケール
docker-compose up -d --scale cms-backend=3

📚 API ドキュメント

ベースパス: http://localhost:3000/api/v1

  • ホームページ: GET / - 統合ブランディングと機能概要
  • API 情報: GET /api/v1 または GET /api/v1/info
  • ヘルスチェック: GET /api/v1/health/liveness, /readiness のサブパスあり)
  • メトリクス (monitoring feature): GET /api/v1/metrics - Prometheus形式のメトリクス
  • 認証 (feature=auth): /api/v1/auth/* - register, login, logout, profile, refresh
  • コンテンツ (feature=database): /api/v1/posts, /api/v1/users, /api/v1/admin/posts
  • API キー管理 (feature=auth,database): /api/v1/api-keys - 作成/一覧/失効
  • 検索 (feature=search): /api/v1/search/* - 全文検索, サジェスト, 統計, 再インデックス
  • OpenAPI UI: GET /api/docs - Swagger UI インターフェース
  • OpenAPI JSON: GET /api/docs/openapi.json - OpenAPI スキーマ

詳細なエンドポイント仕様は /api/docs の Swagger UI を参照してください。

認証

保護されたエンドポイントは Authorization ヘッダに Biscuit アクセストークン (Bearer) を必要とします:

Authorization: Bearer <your-biscuit-token>

または Biscuit を利用する場合:

Authorization: Biscuit <base64-biscuit-token>

OpenAPI では多くの保護エンドポイントで security 配列に [ {"BearerAuth": []}, {"BiscuitAuth": []} ] が付与されており、クライアントはどちらか一方を提示すれば認証が成立します (OR 条件)。公開エンドポイント (login / register / refresh / search など) は security 無しです。

より高度な Biscuit のスコープ/ケイパビリティ定義例は docs/BISCUIT.md を参照してください。

リクエスト例(主要ルート)

ログインしてトークンを取得

curl -X POST http://localhost:3000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "demo_user",
    "password": "<your_password>"
  }'

投稿の作成

curl -X POST http://localhost:3000/api/v1/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your_token>" \
  -d '{
    "title": "最初の投稿",
    "content": "これは最初の投稿の本文です。",
    "published": true
  }'

投稿一覧の取得(ページネーション付き)

curl "http://localhost:3000/api/v1/posts?page=1&limit=10"

検索(feature=search)

curl "http://localhost:3000/api/v1/search?q=rust"

(その他: drill --benchmark benchmark.yml などのベンチマークコマンド参照)

詳細: 設定・パフォーマンス・監視・テスト等

本番運用向けの詳細(環境変数一覧、パフォーマンスチューニング、監視・ヘルスチェック、ロードテスト、セキュリティ設定など)は README_PRODUCTION.md にまとめてあります。トップ README には開発・ビルドの最小手順と参照先のみを掲載しています。

必要であれば README_PRODUCTION.md の特定セクション(例: デプロイ手順、監視設定)をトップ README に抜粋します。どのセクションを抜粋するか指示してください。

🤝 コントリビュート

  1. リポジトリを Fork する
  2. 機能用ブランチを作成する (git checkout -b feature/amazing-feature)
  3. 変更をコミットする (git commit -m 'Add amazing feature')
  4. 新機能にはテストを追加する
  5. すべてのテストが通ることを確認する (cargo test)
  6. ブランチを Push する (git push origin feature/amazing-feature)
  7. プルリクエストを作成する

📝 ライセンス

このプロジェクトは MIT ライセンスの下で公開されています。詳細は LICENSE ファイルを参照してください。

🆘 サポート

  • ドキュメント: API ドキュメントは GET /api/docs で確認できます
  • Issues: バグは GitHub Issues へ報告してください
  • パフォーマンス: インサイトには /api/v1/metrics エンドポイントを使用してください
  • 監視: 本番監視には Prometheus の導入を推奨します
  • 詳細: より詳細な本番運用情報は README_PRODUCTION.md を参照してください

🎯 アーキテクチャの特徴

この CMS バックエンドは、統合された単一バイナリ cms-server として実装されています。

統合されたバイナリ構成

メインバイナリ: cms-server

  • cms-lightweight, cms-simple, cms-unified の機能を統合
  • feature フラグにより本番モード/開発モードを切り替え可能
  • 単一のエントリポイントで全機能を提供

補助バイナリ:

  • cms-admin: 管理・運用用 CLI
  • cms-migrate: データベースマイグレーション
  • 開発支援ツール (dev-tools feature): dev-tools, admin_server, run_docs など

✅ パフォーマンス改善

  • データベース接続プーリング: PostgreSQL 向けに Diesel + deadpool で実装
  • Redis キャッシュ: 自動無効化を含む多層キャッシュ戦略
  • レートリミッター: エンドポイント毎のインテリジェントな制御
  • 非同期処理: Tokio ベースの完全な async/await 実装

✅ セキュリティ改善

  • Biscuit 認証: Capability ベースのトークン認証 (Ed25519 署名)
  • API キー認証: Argon2 ハッシュ + SHA-256 lookup hash による O(1) 検証
  • 入力検証: カスタムエラーハンドリングを含む包括的な検証
  • SQL インジェクション防止: パラメタライズドクエリと型安全性
  • CORS 保護: 設定可能なクロスオリジン制御
  • Refresh Token Rotation: セッションバージョン管理による再利用攻撃防止

✅ スケーラビリティ機能

  • 水平スケーリング: ステートレス設計でロードバランサ対応
  • 接続管理: DB/キャッシュ接続の最適化
  • メモリ効率: 効率的なデータ構造とメモリ管理
  • リソース最適化: 高スループット向けのチューニング

✅ 開発者体験

  • OpenAPI ドキュメント: 自動生成される Swagger UI
  • 型安全: Rust による実行時エラー低減
  • 統一レスポンス: ApiResponse<T> による一貫したAPI設計
  • コントラクトテスト: insta によるスナップショットテスト
  • 包括的テスト: ユニット・統合・E2Eテスト

✅ モニタリング & 可観測性

  • Prometheus メトリクス: 包括的メトリクス収集
  • ヘルスチェック: すべてのサービスに対する詳細ヘルス監視
  • 構造化ログ: tracing サポートによる詳細ログ
  • パフォーマンストラッキング: リ��エスト時間などの分析
  • Grafana ダッシュボード: 認証統合進捗監視など

About

No description, website, or topics provided.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 5