Skip to content

feat: API 台帳の優先度判定で永続データの変更とデコレータ以外の認証を考慮する - #1957

Merged
mhaya merged 2 commits into
develop_v2.0.5from
fix/api-inventory-prioritize
Oct 30, 2026
Merged

mhaya merged 2 commits into
develop_v2.0.5from
fix/api-inventory-prioritize

Conversation

@mhaya

@mhaya mhaya commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

概要 (Summary)

  • tools/api-inventory/scripts/prioritize.py の優先度判定を見直す
    • P1 の状態変更系を、データベース/ファイルストレージを作成・更新・削除するものに限る(POST で受ける取得やセッションだけの更新は P1 にしない)
    • infra_auth.py(新規): OAuth2 クライアント認証(@oauth2.token_handler 等)、nginx の location の制限(deny all・auth_basic・if ($var) { return 403; } 等)、Shibboleth SP の requireSession を判定する
    • credential_auth.py(新規): ビュー内のパスワード・トークンの検証を判定する(CSRF・CAPTCHA は除く)
    • 上記の認証がある行は auth_required が「不要」でも無認証として扱わず P5 にする
    • 管理者向け(admin-access 相当)の API を「対象外」にせず、ロールで優先度を付ける。ID 直指定の懸念(bola_risk ★)がある書き込み系は P2・読み取り系は P3、リポジトリ/コミュニティ管理者も使える書き込み系は管轄の限定を確かめるため P3、それ以外は P5
    • docstring と README を実際の判定に合わせる
  • アプリ本体のコードは変更しない
  • 動作確認: python3 -m pytest tools/api-inventory/tests(43 件パス)

関連Issue / チケット (Related Issues)

  • close #

変更タイプ (Type of Change)

  • 🚀 新機能追加 (Feature)
  • 🐛 バグ修正 (Bug Fix)
  • 🔒 セキュリティ修正 (Security Fix)
  • 🚫 機能のクローズ・非公開化・削除 (Feature Deprecation/Disable)
  • ⚠️ 破壊的変更・データ移行を伴う修正 (Breaking Change / Migration)
  • 📚 仕様書・マニュアル・APIリストの更新 (Documentation)

🤖 0. CI 自動チェック (API Inventory Drift)

PR ごとに WEKO3 コンテナを起動し、url_map のダンプ・台帳との突き合わせ・変更行の
到達可否測定を自動実行する。結果は PR コメントと Actions の artifact
(api-inventory-summary) に出る。

このリポジトリは public のため、台帳もベースラインも同梱していない。
実データはプライベートリポジトリ RCOSDP/weko-secret にあり、CI は Secret 経由で取得する。
以降この文書では、そこを単にプライベートリポジトリと呼ぶ。

台帳はブランチごとに内容が違うため、CI は weko 側と同名のブランチを
プライベートリポジトリから探して使う(head → base → 既定ブランチ の順)。
採用されたブランチ名は PR コメントの冒頭に出るので、件数を読む前にそこを見ること。
対応ブランチが無い場合は既定ブランチと比較され、コメント冒頭に警告が出る。
その件数は当てにならないので、PASS でも「確認済み」と読まないこと。
詳細: tools/api-inventory/ci/README.md §3a

  • CI が PASS している、または FAIL の各項目に対処済み
    Secret (API_INVENTORY_REPO / API_INVENTORY_SSH_KEY) が未設定のリポジトリ、
    および fork からの PR では、このジョブは何もせずスキップされる。

API を追加・変更した場合(必須)

  • プライベートリポジトリ側の作業ブランチを、この PR のブランチと同名で切った
    この PR が fix/issue62569 → develop_v2.0.4 なら、プライベート側も
    fix/issue62569 → develop_v2.0.4。同名にしておけば台帳 PR が未マージでも
    CI がそれを見るので、2つの PR のマージ順を気にしなくてよい。
  • プライベートリポジトリの api_snapshot.json を更新し、対応する PR を出した
    bash export WEKO_API_INVENTORY_DIR=/path/to/weko-secret ./install.sh python3 tools/api-inventory/scripts/snapshot.py --out "$WEKO_API_INVENTORY_DIR/api_snapshot.json"
    更新しないと CI が落ちる。公開リポジトリのコード変更とは別の PRになる。
  • プライベートリポジトリの weko3_api_list_full.tsv に行を追加・更新し、
    build_checklist.py で 24 列版を再生成した(未収載だと reconcile が FAIL する)
  • 台帳・スナップショット・実測結果をこの公開リポジトリにコミットしていない
    (git status に *.tsv / api_snapshot.json が出ていないこと)

FAIL したときの対処(要約)

まず PR コメント冒頭の台帳ブランチを見る。警告が出ていれば、件数を追う前に
プライベートリポジトリ側の対応ブランチを用意すること(比較相手が違うので件数に意味がない)。

ジョブが落ちる条件は 3 つある。PR コメントのどのセクションに件数が出ているかで切り分ける。

落ちた場所 落ちる条件
ベースラインとの差分 (drift.md) G1〜G7 のいずれかに該当
台帳との突き合わせ (reconcile.md) A + B + C + D + E の合計が 1 件以上
変更行の到達可否測定 (probe) G8 / G9 に該当(結果は artifact に含めないので Actions のログで件数を見る)
検出 意味 対処
G1 / G2 新規経路に認証系デコレータが無い / 認証系デコレータが削除された 実装を直す。意図的な公開なら台帳に根拠を書いてベースライン更新
G3 認証・認可デコレータのコメントアウトが増えた 原則やり直し。残す場合は理由をコード中のコメントに明記する
G4 *_PERMISSION_FACTORY / CSRF 保護 等が危険側の値に変わった 原則やり直し
G5 ModelView の can_delete / can_export が False → True 意図的なら台帳の data_op を更新
G6 静的解析で属性が取れない経路が追加された 台帳に行を追加してレビューする(外部ライブラリ由来など)
G7 依存パッケージの更新で経路が増減した 増えた経路は台帳に追加。消えた経路は行を削除するか allow に登録
G8 台帳で data_op が作成/更新/削除の経路に、未認証で到達した 原則やり直し。意図的な公開なら台帳の根拠を更新。data_op の記載誤りなら台帳を直す
G9 台帳では遮断なのに実測で到達(認可の回帰) 原則やり直し
reconcile A / E 実機にあるが台帳に無い(A: URI 単位 / E: 同一 URI の endpoint 単位) 台帳に行を追加する
reconcile B 台帳にあるが実機の url_map に無い 理由を確認し、正当なら allow に登録する
reconcile C / D メソッド・app 列の記載誤り 台帳を実機に合わせる

reconcile B のうち、実機に存在しないことが正当な行(プラグイン未登録・config で無効等)は
プライベートリポジトリの reconcile_allow.json に理由付きで登録する。理由なしの登録は不可。
登録済みの行は B'(既知・許容)として集計され、E'(endpoint が実機に無い)と併せてゲート対象外になる。

W1〜W6 は WARN でゲートは通るが、レビューでは見ること
(ModelView の追加 / 実装本体の変化 / HTTP メソッド・URL の変化 / 監視対象 config の変化 /
依存パッケージの版の変化)。特に W6(依存の版)は、ベースラインを CI と異なる環境で作ると
毎回出続けて形骸化するため、ベースラインは install.sh で作った環境から生成する。

CI の出力は件数のみ。該当した経路名は Actions には出ないので、プライベートリポジトリ側の
完全版レポート(--summary-only なしで再実行したもの)で確認すること
(このリポジトリは public で、ログ・artifact・PR コメントは誰でも読めるため)。


🔒 1. セキュリティ & API アクセス制御チェック (必須)

認証・認可 (Authentication & Authorization)

  • 新規/変更された Blueprint・View・REST リソースに適切なデコレータ / Permission を設定している
    • 例: @login_required, @pass_record, need(...), Invenio Access Action
    • /api/* では Permission.require(http_exception=403) を使うこと。
      @login_required は API アプリに security.login が無いため 401 ではなく 500 になる
    • CI: G1 / G2 が自動検出(デコレータの有無・削除)
  • 状態変更・破壊的メソッド (POST / PUT / PATCH / DELETE) の権限が正しく制限されている
    • CI: G8 が変更行を未認証で実測(使い捨て環境なので --allow-writes 付きで
      GET / HEAD 以外も叩く)
  • 未ログイン(Anonymous)状態でアクセスした際、意図しないデータ取得・変更が拒絶される
    • CI: G8 / G9 が変更行を実測。ただし測定対象は変更行のみ、かつ既定プロファイルで
      起動した経路のみ。ワークフロー系など未解決プレースホルダの行は skip される
  • 認可を config の permission factory に委ねている場合、None で無効化していない
    • CI: G4 が *_PERMISSION_FACTORY 等を監視

機能クローズ・非公開化の場合 (Feature Disable)

  • UI(画面・ボタン)の非表示だけでなく、バックエンド API(ルーティング・View)も完全に遮断されている
  • 無効化状態で直接 API を叩いた場合、404 Not Found または 403 Forbidden が返ることを確認した

🧪 2. テストコード観点チェック (pytest / Invenio Test Suite)

権限・異常系テスト (Negative & Authorization Tests)

  • 未認証アクセス (Anonymous): トークン/セッションなしのリクエストで 401 Unauthorized または 403 Forbidden / 404 Not Found が返ることを検証するテストがある
  • 権限不足ユーザー (Forbidden): 閲覧権限のみのユーザーが更新/削除 API を叩いた際に 403 になるテストがある
  • 無効化/非公開機能の遮断テスト: 対象機能が無効化されている場合、エンドポイントが 404 / 403 を返すテストがある

境界値・入力バリデーションテスト (Boundary & Validation)

  • 不正なパラメータ(巨大ファイル、異常な MIME タイプ、無効な JSON/XML スキーマ、SQLi/XSS ペイロード等)で適切に 400 Bad Request / バリデーションエラーが返るテストがある

データ整合性・トランザクションテスト (Integrity & Rollback)

  • ファイルストレージ(S3/ローカル)書き込み失敗時や DB エラー時に、中途半端なレコードやゴミファイルが残らずロールバックされるテストがある

🛡️ 3. データ保護 & 破壊的変更防止チェック (Data Safety)

  • 物理削除・上書きの安全性:
    • ファイル・アイテム・メタデータの完全削除/置換処理に、意図しない一括削除や別レコードへの誤適用リスクがない
    • 論理削除、バージョン管理、バックアップ等のロールバック機構が考慮されている
  • トランザクション整合性:
    • DB 更新とストレージ操作がアトミックに管理されている

⚙️ 4. マイグレーション & システム影響チェック (Invenio / WEKO3 Stack)

データベース (DB / Alembic)

  • invenio alembic upgrade(適用)および downgrade(ロールバック)スクリプトを作成・検証した
  • 既存データに対する破壊的変更(カラム削除、型変更、NOT NULL 制約追加等)の移行スクリプト/データパッチを用意した

検索インデックス (Elasticsearch / OpenSearch)

  • マッピング定義変更の有無を確認した
  • インデックス再作成(Reindex)やエイリアス切り替え手順を準備・検証した

設定 & 非同期処理 (Config / Celery / Cache)

  • invenio.cfg / 環境変数のデフォルト値を設定した
  • Celery タスクのシグネチャ変更によるキュー滞留・不整合が発生しない
  • キャッシュ(Redis/Memcached)のパージが必要か確認した

📚 5. ドキュメント・仕様書更新チェック (weko-document)

  • API インベントリ: ツールは本リポジトリの tools/api-inventory/、
    台帳・調査記録はプライベートリポジトリ(public リポジトリには置かない)。
    §0 のチェック項目で対応済みなら、ここは確認のみ。
    • エンドポイントの追加・変更・廃止、メソッド、認証・認可要件、リクエスト/レスポンス仕様を更新した
    • 調査記録(weko3_api_auth_findings.md)もプライベートリポジトリに置く。台帳は二重管理しない
  • WEKO3 機能仕様書:
    • 対象機能の仕様追加・変更・クローズ(非公開化)内容を反映した
  • 各種マニュアル (管理者 / 利用者マニュアル):
    • 画面導線・操作手順・権限仕様の変更を反映した
  • 更新不要な場合(理由):

📋 6. 動作検証エビデンス (Verification Evidence)

テスト実行結果

cd modules/<対象モジュール> && pytest
# -> PASS

CI の成果物 (artifact: api-inventory-summary)

ファイル 内容
drift.md ベースラインとの差分(件数のみ)
reconcile.md 台帳と実機の突き合わせ(件数のみ)

明細(該当した経路名・実測結果)は公開できないため artifact に含めていない。
プライベートリポジトリ側で同じコマンドを --summary-only なしで実行して確認する。

手動で確認したこと

🤖 Generated with Claude Code

Summary by Sourcery

API インベントリの優先度判定を、永続データ変更とデコレータ以外の認証方式および管理者ロールを考慮するよう見直してください。

New Features:

  • API インベントリの優先度判定が、永続データの変更範囲、インフラ認証、ビュー内の資格情報認証を考慮するようになりました。
  • 管理者向け API を対象外にせず、ロールと ID 直接指定リスクに応じて優先度を付けるようになりました。

Bug Fixes:

  • POST で受ける取得処理やセッション・Redis・検索基盤などのみを変更する API が、状態変更系として過大評価される問題を修正しました。
  • デコレータ以外の認証を無認証として扱う問題を修正しました。

Enhancements:

  • OAuth2、nginx、Shibboleth、パスワード、トークンによる認証検出を追加しました。
  • 優先度判定とテスト観点による引き上げ基準を見直し、認証・情報露出・未使用 API の分類を更新しました。

Documentation:

  • API インベントリの優先度判定基準と実行手順を実際の判定ロジックに合わせて更新しました。

Tests:

  • インフラ認証、ビュー内認証、永続データ変更、管理者向け API の優先度判定テストを追加しました。

- P1 の状態変更系は、データベース/ファイルストレージを作成・更新・削除する
  ものに限る(POST で受ける取得やセッションだけの更新を含めない)
- infra_auth: OAuth2 クライアント認証、nginx の location の制限、
  Shibboleth SP の requireSession を判定する
- credential_auth: ビュー内のパスワード・トークンの検証を判定する
- 上記の認証がある行は auth_required が「不要」でも無認証として扱わない
- docstring と README を実際の判定に合わせる

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c8ac0b43-e293-49dd-a18f-5d52497eed68

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

🔍 Claude によるレビュー

指摘 2 件 — 🔴 高 0 / 🟠 中 1 / 🟡 低 1 / 🔎 未確認 8 件


🟠 [中] data_store が '-' や書式外の行では、無認証の書き込みが P1 に入らなくなった

tools/api-inventory/scripts/prioritize.py:207 (1/3 パス)

P1 の条件に is_mutating(=data_store に PostgreSQL/ファイルが明記されていること)が加わった。data_store が未記入('-')または書式が違う行は、無認証の POST/PUT/DELETE でも P1 にならない。同じ行は P4 の公開設計に当たらなければ「分類条件に合致せず」の P3 に落ちる。

提案

data_store が '-' や空で保存先を判別できない書き込み行は、安全側として P1 のままにするか、P2 に置く。

根拠
persists = bool(PERSISTENT_STORE_RE.search(store))
is_mutating = persists and any(k in data_op for k in ('作成', '更新', '削除'))
...
if is_write_method and is_mutating and (no_auth or unauth_reach) and not creates_only:

確認: prioritize.py:150-345 を読んだ。is_mutating が使われるのは P1 の2条件だけ。P1 を外れた行の落ち先は P2 の各条件、管理者向け、P4、読み取り系 P3、P5、既定の P3 の順。台帳 TSV は非公開リポジトリにあり、data_store が実際に '-' の書き込み行が何件あるかは確認していない。


🟡 [低] 区分一覧に廃止した「対象外」が残っている

tools/api-inventory/scripts/_report.py:66 (1/3 パス)

prioritize.py の ORDER から「対象外」は削除されたが、レポート生成側は「対象外」を集計し続ける。常に 0 件の行が出力され、区分の廃止が反映されない。

提案

タプルから '対象外' を外す。

根拠
for k in ('P1','P2','P3','P4','P5','整理対象','環境依存','対象外'):

確認: grep で tools/api-inventory 配下の *.py を検索し、_report.py:66 だけが「対象外」を区分として参照していることを確認した。_report.py:55-70 も読んだ。reconcile.py の「対象外」は別の意味(比較対象外)なので無関係。


🔎 未確認 — 裏が取れなかったもの 8 件
  • ビュー内の本人認証の検出が広すぎて、無認証の書き込みを P5 に下げる恐れがある tools/api-inventory/scripts/credential_auth.py:133 (1/3 パス)
    • 実装関数と、その呼び出し先を1段たどった範囲のどこかに verify_password や「検証の動詞+token」の関数名があれば、auth_required が不要でも cred として扱い、no_auth=False にする。その呼び出しが本当にリクエストの認可を決めているかは見ていない。書き込み系の行がログインの分岐とは無関係に検証関数を呼んでいても P5 になり、P1/P2 から外れる。
    • 確認できなかった理由: 検出結果と実際のコードを突き合わせるには、非公開リポジトリの台帳と対象ビューの実体が要る。差分内のテストは単純な例しか扱わない。
  • nginx の location 判定を SP の RequestMap にそのまま当てている tools/api-inventory/scripts/infra_auth.py:187 (1/3 パス)
    • nginx の location ~ /secure/ は前方一致でなく、パスの途中にも一致する。一方 _requires_shib_session は SP 側の Path を前方一致で見る。同梱の shibboleth2.xml は Host 全体が requireSession=true なので、Path に当たらないパスもすべて保護済みと判定される。実運用の SP 設定が違えば、保護されていない location を保護済みと誤判定しうる。
    • 確認できなかった理由: サイトごとの nginx と SP の実設定を確認できない。README にも同梱設定だけを読むと明記されている。
  • トークン検証の正規表現が広く、P1/P2 の行を P5 に下げうる tools/api-inventory/scripts/credential_auth.py:34 (1/3 パス)
    • (?:verify|validate|check|confirm|convert)\w*token と token\w*_(?:status|valid) は、本人確認ではない関数名にも一致しうる。一致して、かつ★実証が無い行は、無認証の書き込み系でも P5 になり、優先度が下がる(認可の見逃し)。例: トークンの存在確認や期限確認だけの関数。
    • 確認できなかった理由: 実際の台帳 TSV と対象リポジトリ全体の関数名に対して一致する関数を列挙しておらず、誤一致が実在するか確かめきれなかった。
  • nginx の deny all を allow の範囲や satisfy に関係なく保護とみなしている tools/api-inventory/scripts/infra_auth.py:240 (1/3 パス)
    • deny all があれば守られていると判定する。同じ location の allow が広い範囲を許可している場合や satisfy any の場合でも、保護ありと判定し、P5 に下げる可能性がある。
    • 確認できなかった理由: リポジトリ同梱の nginx/weko.conf に該当する location があるか確認していない。ただしテストでは allow 127.0.0.1; deny all; を保護ありとして期待している。
  • Shibboleth の RequestMap を Host 名に関係なく評価している tools/api-inventory/scripts/infra_auth.py:218 (1/3 パス)
    • _requires_shib_session は全 Host 要素のどれかで requireSession が有効なら True を返す。nginx の server_name と対応する Host かどうかは見ていない。複数の Host があり設定が異なる場合は誤判定になる。
    • 確認できなかった理由: 同梱の shibboleth2.xml に Host 要素が複数あるか確認していない。
  • 永続データ判定の導入で、無認証の書き込み系が P1 から外れる tools/api-inventory/scripts/prioritize.py:245 (1/3 パス)
    • P1 の条件に is_mutating(data_store が PostgreSQL/ファイル)を加えたため、data_store が '-' や未記載の無認証書き込み行は P1 にならない。classify を読むと P2 の分岐も通らず、最後の「分類条件に合致せず」の P3 に落ちるか、PUBLIC_BY_DESIGN に一致すれば P4 になる。ledger の data_store の記載漏れがそのまま認可上の見逃しに直結する。
    • 確認できなかった理由: 台帳の実データがリポジトリに無く、data_store が欠落している行が実際にどれだけあるか確認できなかった。PERSISTENT_STORE_RE が実際の記載('ファイル実体:…' など)に一致するかも確認できていない。
  • トークン・パスワード検証の呼び出しがあるだけで P5 になり、結果の使用有無を見ていない tools/api-inventory/scripts/credential_auth.py:146 (1/3 パス)
    • 関数名の正規表現と1段の呼び出し追跡だけで本人認証ありと判定する。検証結果を使わない呼び出しや、認証の必要な分岐と無関係な呼び出しでも P5 に下がる。cred が立つと実測の「未認証で到達」も(★実証が無ければ)無視されるため、書き込み系が P1 から P5 に落ちうる。
    • 確認できなかった理由: ledger が無く、実際の誤判定の有無を確認できなかった。実装ビューへの適用結果を見ないと実害の程度が分からない。
  • _requires_shib_session が Host 名を照合せず、どれかの Host で requireSession が true なら True にする tools/api-inventory/scripts/infra_auth.py:191 (1/3 パス)
    • nginx の server_name と shibboleth2.xml の Host name を突き合わせていない。複数 Host があり一部だけ requireSession が有効な設定では、保護されていない側のパスも保護済みと判定される。
    • 確認できなかった理由: 同梱の shibboleth2.xml は Host が1つのものしか確認していない。複数 Host 構成の運用環境は未確認。

モデル sonnet / 3 回実行して和集合 / コスト $0.6124。同じ差分でも結果が揺れるため複数回まわし、一部のパスでしか挙がらなかったものには回数を添えています

差分のみを対象にした自動レビューです。誤りが含まれることがあります。

- 「対象外」を廃止し、admin-access 相当の行も確認対象にする
- bola_risk に★がある行は書き込み系を P2、読み取り系を P3 にする
- リポジトリ/コミュニティ管理者も使える書き込み系は、管轄の限定を
  確かめるため P3 にする
- 上記以外(管理者向けの読み取り系・システム管理者のみ)は P5 にする

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

API インベントリ差分(件数のみ)

⚠️ プライベートリポジトリに対応ブランチが無いため、既定ブランチの台帳と比較しています。
ブランチ間の経路差がそのまま差分として出るので、以下の件数は当てになりません。
この PR のブランチと同名のブランチをプライベートリポジトリに作ってください。

明細は公開できないため件数のみ表示しています。該当箇所はプライベートリポジトリ側の台帳・レポートで確認してください。

ベースラインとの差分

API インベントリ差分レポート

  • 旧: 5f4bef44c v2.0.4 (profile=default) endpoints=928 (外部ライブラリ由来 359)
  • 新: 81fe3ffee v2.0.4-7-g81fe3ffee (profile=default) endpoints=928 (外部ライブラリ由来 359)

判定: ✅ PASS (FAIL 0 / WARN 2)

サマリ

分類 件数
ADDED 0
REMOVED 0
RULE_CHANGED 0
METHODS_CHANGED 0
AUTH_CHANGED 2
IMPL_CHANGED 0
ATTRS_UNKNOWN_NEW 0
ModelView 追加 0
ModelView 削除 0
ModelView フラグ変化 1
config 変化 1
コメントアウト認証の増加 0
依存パッケージの版変化 6

[WARN] W6 依存パッケージの版が変化した — 6件

  • distlib — 0.4.3 -> 0.4.4
  • frozendict — 2.4.7 -> 2.5.0
  • pbr — 7.0.3 -> 7.1.3
  • pyld — 3.1.0 -> 3.3.0
  • orjson — 3.6.1 -> (削除)
  • weko-redis — 0.1.0.dev20170000 -> (削除)

[WARN] W5 監視対象 config が変化した — 1件

件数のみ。該当の経路名はプライベートリポジトリ側の完全版レポートを参照。


台帳との突き合わせ

スナップショット ↔ インベントリ 突き合わせ

  • リビジョン: 81fe3ffee v2.0.4-7-g81fe3ffee 経路URI=908
  • 台帳: 行=1048 URI=919

件数のみ。詳細はプライベートリポジトリ側の完全版レポートを参照。

判定: ✅ 一致 (0件)

検出 件数
A. インベントリ未収載(抽出漏れ) 0
B. 実機に無い(未説明) 0
B'. 実機に無い(既知・許容) 11
C. メソッド不一致 0
D. app列の不一致 0
E. endpoint 未収載 0
E'. endpoint が実機に無い(参考) 1

@sourcery-ai

sourcery-ai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

API 台帳の優先度判定を、永続データの変更範囲、OAuth2/nginx/Shibboleth/ビュー内認証、管理者ロールと IDOR リスクを考慮するモデルへ改訂し、認証・設定解析および分類ロジックを追加の pytest で検証している。

Sequence diagram for non-decorator authentication detection

sequenceDiagram
    participant P as prioritize.py
    participant I as infra_auth
    participant C as credential_auth
    participant S as Source and config files
    P->>I: detect(uris, methods, impl_file, impl_line)
    I->>S: Read OAuth2 decorators, nginx config, Shibboleth config
    S-->>I: Authentication matches or none
    alt infrastructure authentication found
        I-->>P: OAuth2, nginx, or Shibboleth authentication
    else no infrastructure authentication
        P->>C: credential_auth(impl_file, impl_line, endpoint)
        C->>S: Parse view and one-level package calls
        S-->>C: Password or token verification matches
        C-->>P: Credential authentication or empty result
    end
    P->>P: Treat matched authentication as authenticated
    P-->>P: Classify as P5 unless stronger risk rules apply
Loading

Flow diagram for API inventory priority classification

flowchart TD
    A[API inventory row] --> B[Detect authentication]
    B --> C[infra_auth: OAuth2 nginx Shibboleth]
    B --> D[credential_auth: password or token]
    C --> E[Determine persistent data change]
    D --> E
    E --> F{Database or file storage changed?}
    F -->|Yes| G[Apply P1 or P2 write-risk rules]
    F -->|No| H[Exclude session Redis ES and external-only changes from P1]
    G --> I[Apply exposure and authorization rules]
    H --> I
    I --> J{Administrative API?}
    J -->|Yes| K[Use roles and bola_risk for P2 P3 or P5]
    J -->|No| L[Apply ordinary priority rules]
    K --> M[Apply test-gap bump up to P3]
    L --> M
    M --> N[Priority and reason]
Loading

Flow diagram for persistent-data and administrative risk rules

flowchart TD
    A[API inventory row] --> B{Persistent store?}
    B -->|PostgreSQL or file storage| C{Create update or delete?}
    B -->|Session Redis ES or external service only| D[Not persistent mutation]
    C -->|Write with missing or ineffective authorization| E{Create only?}
    C -->|No| F[Apply read and exposure rules]
    E -->|No| G[P1]
    E -->|Yes| H[P2]
    E -->|No persistent mutation| F
    D --> F
    F --> I{Administrative API without finding?}
    I -->|bola_risk star and write| J[P2]
    I -->|bola_risk star and read| K[P3]
    I -->|Scoped admin write| L[P3]
    I -->|Scoped admin read or system admin only| M[P5]
    I -->|No| N[Ordinary classification]
Loading

File-Level Changes

Change Details Files
永続データの変更だけを状態変更リスクとして扱うよう、優先度分類と関連する引き上げ・整理対象ルールを更新した。
  • PostgreSQL/ファイルストレージの作成・更新・削除を P1 判定の対象に限定
  • 取得系、セッション・Redis・ES・外部サービスのみの変更を P1 から除外
  • 新規作成のみ、情報露出、未利用行、テスト観点不足の優先度を新しい P1〜P3 基準に合わせて調整
tools/api-inventory/scripts/prioritize.py
tools/api-inventory/scripts/README.md
デコレータに現れない認証方式をソース・設定解析で検出し、無認証判定の誤検出を防止する仕組みを追加した。
  • OAuth2 token/revoke handler を AST 解析で検出
  • nginx の location、アクセス制限、認証設定、method-dependent な if/map、limit_except を解析
  • Shibboleth RequestMap の requireSession と shib_request の組み合わせを確認
  • ビュー内のパスワード/トークン検証と同一パッケージ内の一段階の呼び出しを検出
  • CSRF・CAPTCHA・トークン発行を本人認証から除外し、認証検出行を P5 として扱う
tools/api-inventory/scripts/infra_auth.py
tools/api-inventory/scripts/credential_auth.py
tools/api-inventory/scripts/prioritize.py
管理者向け API を対象外から確認対象へ変更し、ロールと IDOR 懸念に応じて優先度を分類するようにした。
  • bola_risk のある書き込みを P2、読み取りを P3 に分類
  • リポジトリ/コミュニティ管理者が使える書き込みを管轄確認のため P3 に分類
  • スコープ付き管理者の読み取りとシステム管理者限定 API を P5 に分類
  • 管理者向け API に対するテスト観点不足の P3 引き上げを適用
tools/api-inventory/scripts/prioritize.py
tools/api-inventory/scripts/README.md
新しい認証検出と優先度モデルを検証するテストを追加した。
  • 認証情報検出の直接呼び出し、一段階の委譲、曖昧な関数名、フレームワーク endpoint を検証
  • nginx、Shibboleth、OAuth2 の location・method・設定差分を検証
  • 永続データ判定、認証情報ビュー、管理者ロール別分類、IDOR 懸念を検証
tools/api-inventory/tests/test_credential_auth.py
tools/api-inventory/tests/test_infra_auth.py
tools/api-inventory/tests/test_prioritize.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New security issues found

"""SP の RequestMap で path に requireSession が効いているか。"""
p = _conf_path('WEKO_SHIB_CONF', 'nginx/shibboleth2.xml')
try:
root = ET.parse(p).getroot()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.use-defused-xml-parse): The native Python xml library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service. Do not use this library to parse untrusted input. Instead the Python documentation recommends using defusedxml.

Suggested change
root = ET.parse(p).getroot()
root = defusedxml.etree.ElementTree.parse(p).getroot()

Source: opengrep

@mhaya
mhaya merged commit 23a66ec into develop_v2.0.5 Oct 30, 2026
31 of 98 checks passed
@github-actions

Copy link
Copy Markdown

API インベントリ差分(件数のみ)

⚠️ プライベートリポジトリに対応ブランチが無いため、既定ブランチの台帳と比較しています。
ブランチ間の経路差がそのまま差分として出るので、以下の件数は当てになりません。
この PR のブランチと同名のブランチをプライベートリポジトリに作ってください。

明細は公開できないため件数のみ表示しています。該当箇所はプライベートリポジトリ側の台帳・レポートで確認してください。

ベースラインとの差分

API インベントリ差分レポート

  • 旧: 5f4bef44c v2.0.4 (profile=default) endpoints=928 (外部ライブラリ由来 359)
  • 新: b0865274b v2.0.4-8-gb0865274b (profile=default) endpoints=928 (外部ライブラリ由来 359)

判定: ✅ PASS (FAIL 0 / WARN 2)

サマリ

分類 件数
ADDED 0
REMOVED 0
RULE_CHANGED 0
METHODS_CHANGED 0
AUTH_CHANGED 2
IMPL_CHANGED 0
ATTRS_UNKNOWN_NEW 0
ModelView 追加 0
ModelView 削除 0
ModelView フラグ変化 1
config 変化 1
コメントアウト認証の増加 0
依存パッケージの版変化 6

[WARN] W6 依存パッケージの版が変化した — 6件

  • distlib — 0.4.3 -> 0.4.4
  • frozendict — 2.4.7 -> 2.5.0
  • pbr — 7.0.3 -> 7.1.3
  • pyld — 3.1.0 -> 3.3.0
  • orjson — 3.6.1 -> (削除)
  • weko-redis — 0.1.0.dev20170000 -> (削除)

[WARN] W5 監視対象 config が変化した — 1件

件数のみ。該当の経路名はプライベートリポジトリ側の完全版レポートを参照。


台帳との突き合わせ

スナップショット ↔ インベントリ 突き合わせ

  • リビジョン: b0865274b v2.0.4-8-gb0865274b 経路URI=908
  • 台帳: 行=1048 URI=919

件数のみ。詳細はプライベートリポジトリ側の完全版レポートを参照。

判定: ✅ 一致 (0件)

検出 件数
A. インベントリ未収載(抽出漏れ) 0
B. 実機に無い(未説明) 0
B'. 実機に無い(既知・許容) 11
C. メソッド不一致 0
D. app列の不一致 0
E. endpoint 未収載 0
E'. endpoint が実機に無い(参考) 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant