Skip to content
Published on

銀行でプラットフォームエンジニアリングをやる — Backstageとガバナンスの結婚

Authors

はじめに

金融機関でマイクロサービスを1つ新設するには何が必要でしょうか。コードを書く時間は1日で足りるかもしれません。しかし現実はこうです。Gitリポジトリ作成申請書の決裁、ビルドパイプライン登録依頼、ファイアウォール開放申請(往復数日)、DBアカウント発行申請、セキュリティ審査の受付、資産台帳への登載、監視登録依頼。各ステップごとに担当部署が異なり、決裁ラインが異なり、処理期限が異なります。合計すると3週間から1か月。開発者はその間、コードの代わりに申請書を書いています。

興味深いのは、これらの手続きの一つひとつには、すべて合理的な理由があるという点です。電子金融監督規定のアクセス統制、情報保護ポリシーのセキュリティ審査、資産管理義務、変更統制。問題は手続きの存在ではなく、手続きが人の手で、直列に、書類で実行されていることにあります。

プラットフォームエンジニアリングはこの点を攻めます。手続きをなくすのではなく、手続きをコードに埋め込んで自動的に実行され、自動的に証跡が残るようにすること。本記事はBackstageを中心に、金融機関の内部開発者プラットフォーム(IDP)を設計・運用する方法を扱います。技術的観点の整理であり、個別機関への規制適用はコンプライアンス組織の判断に従ってください。

金融におけるプラットフォームエンジニアリングの価値 — 標準化はコンプライアンス自動化

一般企業でプラットフォームエンジニアリングの価値は主に「開発者体験の改善」と「認知負荷の軽減」で説明されます。金融では、ここに決定的な第三の価値が加わります。

標準化されたゴールデンパスは、それ自体がコンプライアンス自動化の装置です。

  • すべてのサービスが同じテンプレートから生まれれば → セキュリティ設定の漏れが構造的に不可能になります。
  • すべてのデプロイが同じパイプラインを通れば → 変更統制の証跡が自動的に蓄積されます。
  • すべての資産がカタログに登録されれば → 資産管理・所有者指定の義務がデフォルトで充足されます。

セキュリティチーム・監査チームの視点では、点検対象が「バラバラに構成された300のサービス」から「テンプレート5つとパイプライン1つ」に縮むのです。点検コストは桁違いに減り、点検の信頼度は上がります。これが金融プラットフォームエンジニアリングのビジネスロジックであり、経営陣とセキュリティ組織を説得する言語です。

[従来]  サービスごとに異なる構成
  点検 = サービス数 x 点検項目数  (手作業、漏れの可能性)

[IDP]   ゴールデンパスへの収斂
  点検 = テンプレート数 x 点検項目数  (コードレビューで代替可能)
  + テンプレート違反の自動検知 (ポリシーエンジン)

ゴールデンパスに規制要件を内蔵する — Backstageテンプレート

Backstage Scaffolderテンプレートはゴールデンパスの入口です。核心はセキュリティ・監査要件を選択肢ではなくデフォルトとして入れることです。開発者が意識しなくても、セキュリティスキャン、監査ロギング、暗号化設定がオンの状態でサービスが生まれるようにします。

# template.yaml — 金融規制要件を内蔵した新規サービステンプレート
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: secure-spring-service
  title: Spring Bootサービス (セキュアデフォルト内蔵)
  description: セキュリティスキャン、監査ロギング、暗号化が既定で有効な標準サービス
  tags:
    - recommended
    - java
    - compliance-ready
spec:
  owner: platform-team
  type: service

  parameters:
    - title: サービス基本情報
      required:
        - serviceName
        - ownerGroup
        - dataClassification
      properties:
        serviceName:
          title: サービス名
          type: string
          pattern: '^[a-z0-9-]+$'
        ownerGroup:
          title: 所有組織 (人事システムの部署コードと連携)
          type: string
          ui:field: OwnerPicker
        dataClassification:
          title: データ等級 (資産管理報告に使用)
          type: string
          enum:
            - public
            - internal
            - personal-credit    # 個人信用情報 — 追加統制を自動適用
          default: internal

  steps:
    # 1) スケルトン生成 — セキュリティ設定が既に含まれたコードベース
    - id: fetch
      name: 標準スケルトン生成
      action: fetch:template
      input:
        url: ./skeleton
        values:
          serviceName: ${{ parameters.serviceName }}
          owner: ${{ parameters.ownerGroup }}
          dataClass: ${{ parameters.dataClassification }}

    # 2) データ等級がpersonal-creditなら暗号化モジュールを強制注入
    - id: inject-crypto
      name: フィールド暗号化モジュール注入
      if: ${{ parameters.dataClassification === 'personal-credit' }}
      action: fetch:template
      input:
        url: ./addons/field-encryption
        targetPath: ./src

    # 3) 社内Git作成 + ブランチ保護 + CODEOWNERS自動設定
    - id: publish
      name: リポジトリ作成
      action: publish:gitlab
      input:
        repoUrl: gitlab.bank.internal?owner=${{ parameters.ownerGroup }}&repo=${{ parameters.serviceName }}
        defaultBranch: main
        protectDefaultBranch: true

    # 4) セキュリティパイプライン登録 (SAST + SCA + イメージスキャン + 署名)
    - id: pipeline
      name: 標準パイプライン接続
      action: bank:pipeline:register
      input:
        repo: ${{ steps.publish.output.repoContentsUrl }}
        stages: ['sast', 'sca', 'image-scan', 'cosign-sign']

    # 5) 電子決裁の起案 — 新規資産登載の承認 (カスタムアクション、後述)
    - id: approval
      name: 資産登載決裁の上申
      action: bank:approval:submit
      input:
        docType: NEW_SERVICE_REGISTRATION
        serviceName: ${{ parameters.serviceName }}
        dataClass: ${{ parameters.dataClassification }}
        requester: ${{ user.entity.metadata.name }}

    # 6) カタログ登録 — 資産台帳義務の自動充足
    - id: register
      name: カタログ登録
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: '/catalog-info.yaml'

スケルトン側にも規制要件がコードとして入ります。監査ロギング(誰が・いつ・何を)が有効なログ設定、TLSの強制、シークレットは外部ボールト参照のみ許可する設定、標準のヘルスチェックとメトリクスエンドポイントが既定で含まれます。開発者が「セキュリティ要件を勉強して適用する」のではなく、「デフォルトをわざわざオフにしない限り準拠状態」になる構造です。

承認ワークフローの統合 — 電子決裁とScaffolderの接続

金融機関のすべての行為には決裁が付いてきます。IDPが決裁を迂回すれば導入は拒否され、決裁を手作業のまま残せば自動化の意味がありません。答えはScaffolderカスタムアクションで決裁システムを呼び出し、承認完了を待ってから次のステップへ進むことです。

// plugins/scaffolder-backend-module-bank/src/actions/submitApproval.ts
// 概念コード: 電子決裁システム連携のカスタムアクション
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';

export const submitApprovalAction = () => {
  return createTemplateAction<{
    docType: string;
    serviceName: string;
    dataClass: string;
    requester: string;
  }>({
    id: 'bank:approval:submit',
    description: '電子決裁システムに起案を上申し、承認を待機する',
    schema: {
      input: {
        required: ['docType', 'serviceName', 'dataClass', 'requester'],
        type: 'object',
        properties: {
          docType: { type: 'string' },
          serviceName: { type: 'string' },
          dataClass: { type: 'string' },
          requester: { type: 'string' },
        },
      },
    },
    async handler(ctx) {
      const { docType, serviceName, dataClass, requester } = ctx.input;

      // 1) 決裁文書の作成 — データ等級によって決裁ラインが変わる
      //    internal: チームリーダー専決 / personal-credit: リーダー + 情報保護 + CISO
      const approvalLine = dataClass === 'personal-credit'
        ? ['TEAM_LEAD', 'INFOSEC_REVIEW', 'CISO']
        : ['TEAM_LEAD'];

      const doc = await approvalClient.createDocument({
        type: docType,
        title: `新規サービス登載: ${serviceName}`,
        body: renderTemplate(docType, ctx.input),
        approvers: approvalLine,
        drafter: requester,
      });
      ctx.logger.info(`決裁上申完了: ${doc.id}`);

      // 2) 承認待機 — ポーリング (Webhook受信が可能ならイベント駆動で)
      const result = await approvalClient.waitForCompletion(doc.id, {
        timeoutHours: 72,
        pollIntervalSec: 60,
      });

      if (result.status !== 'APPROVED') {
        throw new Error(`決裁差し戻し: ${result.comment ?? '理由未記載'}`);
      }

      // 3) 承認証跡を出力に — 後続ステップとカタログ注釈に記録
      ctx.output('approvalDocId', doc.id);
      ctx.output('approvedAt', result.completedAt);
      ctx.output('approvers', result.approverHistory);
    },
  });
};

設計ポイントは次のとおりです。

  • **決裁ラインをデータ等級の関数にする。**リスクの低い作業はチームリーダー専決で分単位の処理、リスクの高い作業だけセキュリティ組織が介入します。これだけで平均リードタイムが劇的に縮みます。
  • **承認証跡(文書ID、承認者、時刻)をカタログエンティティの注釈として保存します。**監査の際、「このサービスの作成承認証跡」をワンクリックで提示できます。
  • 決裁システムが古いSOAP APIしかなくても、アダプタを一度作ればよいのです。そのアダプタが組織全体の自動化の関門になります。

カタログで資産管理に対応する — システム台帳、所有者、等級

電子金融基盤施設の脆弱性分析評価、資産棚卸し、監督報告 — いずれも「システム一覧と所有者、重要度」を要求します。Excelで管理されていたこの一覧をBackstageカタログが置き換えれば、一覧は常に最新(サービス作成時に自動登載)、所有者は常に有効(人事連携グループ)、等級はポリシーエンジンが参照する生きたデータになります。

# catalog-info.yaml — 監督報告項目とマッピングされるメタデータ
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: loan-application-api
  description: ローン申込受付API
  annotations:
    bank.example.com/asset-id: "AST-2026-0142"        # 資産管理番号
    bank.example.com/approval-doc: "APR-2026-08731"   # 作成承認の決裁文書
    bank.example.com/last-vuln-assessment: "2026-03"  # 直近の脆弱性評価
  labels:
    bank.example.com/data-class: personal-credit
    bank.example.com/criticality: critical
    bank.example.com/dr-tier: tier-2
spec:
  type: service
  lifecycle: production
  owner: group:retail-lending-dev        # 人事システムの部署コードと同期
  system: loan-origination
  dependsOn:
    - resource:loan-db
    - component:customer-master-api
監督・監査の要求項目カタログのマッピング算出方法
情報資産台帳Component/Resourceエンティティ全体カタログAPIで日次抽出
資産ごとの責任者spec.owner (人事連携グループ)グループ長を責任者として解釈
システム重要度criticalityラベル重要度評価の結果をラベルで記録
個人信用情報処理システムdata-classラベルのフィルタラベルクエリ1行
システム間連携状況dependsOnグラフ依存関係グラフのエクスポート
変更承認の証跡approval-doc注釈 + Git履歴決裁IDの逆引き

四半期ごとに資産棚卸しのExcelを作っていた作業が、「カタログAPI呼び出し + 書式変換」のバッチジョブに変わります。さらに重要なのは逆方向の検証です。クラスタで動いているのにカタログに存在しないワークロードをポリシーエンジンが検知すれば、それがそのまま「未登載資産の検知」統制になります。

閉域網でのIDP運用 — エアギャップとミラーリング

金融機関の開発網はインターネットが遮断されているか、プロキシで制限されています。Backstageとそのエコシステムはnpm、コンテナイメージ、プラグインなど外部依存の塊なので、閉域網運用のためのミラーリング体制が先行しなければなりません。

[インターネット区間 — 搬入専用]
  registry.npmjs.org      ghcr.io / docker.io     プラグインソース
        |                       |                       |
        v                       v                       v
  +---------------------------------------------------------+
  |  搬入ゲートウェイ (定期同期 + 脆弱性スキャン + 承認)         |
  +---------------------------------------------------------+
        |                       |
        v                       v
[内部網]
  Nexus/Verdaccio          Harbor
  (社内npmミラー)           (社内イメージレジストリ)
        |                       |
        +----------+------------+
                   v
            Backstageビルド/デプロイ
            (yarn.lockのresolvedを社内ミラーURLに固定)

運用ノウハウをいくつか記しておきます。

  • **バージョン固定と再現可能ビルド。**閉域網で「最新版を取ってきて解決」は不可能です。yarn.lockとイメージdigestを固定し、Backstageのアップグレードは四半期単位の計画作業として扱います。
  • **プラグイン搬入手続きの標準化。**コミュニティプラグインを使うには、ソース搬入 → SCAスキャン → セキュリティレビュー → 社内npm公開の手続きを踏みます。この手続き自体をBackstageテンプレートにしておくとよいでしょう(プラットフォームがプラットフォームをブートストラップ)。
  • **TechDocsも閉域網対応。**ドキュメントビルドに必要なmkdocsイメージ、フォント、プラグインをすべて社内ミラーに置き、外部CDN参照をビルド時に除去します。
  • **外部認証依存の除去。**GitHub OAuthの代わりに社内IdP(Keycloak、AD FS)のOIDCに統一します。

セルフサービスの境界 — 何が自動で、何がレビューか

「すべてセルフサービス」は金融では通用せず、「すべて決裁」はプラットフォームの存在理由を消します。境界はリスク等級マトリクスで引きます。

作業リスク低 (自動承認)リスク中 (リーダー専決)リスク高 (セキュリティレビュー必須)
開発環境ネームスペース作成O------
標準テンプレートの新規サービスO (internal等級)O (対外公開)O (個人信用情報処理)
本番デプロイ (標準パイプライン)O (事前承認済み変更ウィンドウ内)O (ウィンドウ外時間)---
ファイアウォールルール追加---O (社内区間、標準ポート)O (対外区間、非標準)
DBスキーマ変更O (開発)O (本番、非破壊)O (本番、破壊的変更)
シークレット発行/ローテーションO (自動ローテーション)---O (手動の例外発行)
本番データ参照権限------O (時間制限 + 理由必須)

原則は3つです。

  1. リスクの低い作業の承認をなくすのではなく、承認をポリシー通過に置き換えます。「自動承認」の実体はポリシーエンジン(クォータ、等級、テンプレート準拠)による機械審査であり、審査結果が証跡として残ります。
  2. **リスクの高い作業は人のレビューを維持しつつ、レビューに必要な情報をプラットフォームが自動添付します。**セキュリティチームが受け取るレビュー依頼に、データ等級、依存関係グラフ、スキャン結果が最初から付いていれば、レビュー時間は半分以下に減ります。
  3. **境界自体をコードで管理します。**上記マトリクスをYAMLで宣言し、決裁ラインのルーティングがそれを読むようにすれば、境界の調整もPRと決裁で追跡されます。

成熟度の測定 — DORAに規制指標を加える

プラットフォームの成果は測定してこそ予算が付きます。金融ではDORAの4指標に規制対応指標を加えたスコアカードを推奨します。

分類指標導入前 (例)1年後の目標
DORAデプロイ頻度月1回週2回以上
DORA変更リードタイム3週間2日
DORA変更失敗率18%8%以下
DORA復旧時間 (MTTR)4時間30分
規制新規サービスのセキュアデフォルト適用率測定不能100% (テンプレート強制)
規制資産台帳の整合性 (棚卸し比)約70%99%以上
規制脆弱性対応リードタイム (Critical)30日7日
規制未登載資産の検知件数検知不能月間0件へ収束
体験新規サービスセットアップ所要15~20営業日1営業日
体験開発者満足度 (四半期サーベイ)---上昇トレンド

注意すべきは、指標を評価の武器にしないことです。チーム間のランキングを作った瞬間に指標は操作され、プラットフォームは監視ツールと認識されて採用が崩れます。指標はプラットフォーム自体の改善と経営報告にのみ使うという原則を公に明言すべきです。

文化の転換 — セキュリティチームをプラットフォームの顧客に

金融機関のプラットフォームエンジニアリングの成否は、技術よりもセキュリティ・監査組織との関係で決まります。よくある失敗は、プラットフォームチームが開発者だけを顧客と見なし、セキュリティチームを「通過すべき関門」と扱うことです。関門は必ず報復します。

発想を変えてセキュリティチームを第二の顧客として定義します。

  • セキュリティチームのペインポイント(手作業の点検、証跡収集、資産状況の把握)をインタビューし、それをプラットフォーム機能にします。「点検対象の全サービスのスキャン結果を1画面で」のような機能は、セキュリティチームをプラットフォームの最も熱烈な支持者に変えます。
  • ゴールデンパスのセキュアデフォルトをセキュリティチームと共同所有します。テンプレートリポジトリのCODEOWNERSにセキュリティチームを入れ、セキュリティ設定の変更はセキュリティチームのレビューを通すようにします。セキュリティチームが「プラットフォームを承認する」のではなく「プラットフォームを共に作る」構造です。
  • 監査対応シーズンにプラットフォームが証跡算出を代行すれば、その経験が組織全体にプラットフォームの価値を刻み込みます。

ケースシナリオ — 3週間が1日になる道筋

仮想のシナリオで前後を比較します。リテール与信チームがローン限度額照会APIを新設するケースです。

[導入前 — 21営業日]
D1~D3   : Gitリポジトリ申請書の作成、決裁待ち、インフラチームの手動作成
D4~D8   : パイプライン登録依頼、CI担当者のキュー待ち
D6~D10  : ファイアウォール開放申請 (DB、社内API2件) — セキュリティチームのレビューキュー
D8~D12  : DBアカウント発行、シークレットの手動受け渡し (メッセンジャーで... 事故リスク)
D10~D15 : セキュリティ審査 — チェックリスト手作業作成、差し戻し1回
D15~D18 : 資産台帳への登載、監視登録依頼
D19~D21 : 本番デプロイ決裁、初回デプロイ
開発者の実感: 「コードより申請書を多く書いた」

[導入後 — 1営業日]
09:00  Backstageポータルでsecure-spring-serviceテンプレートを実行
       (サービス名、所有組織、データ等級 = personal-creditを入力)
09:01  リポジトリ・パイプライン・監視・カタログを自動作成
       ファイアウォール標準ポリシー自動申請 (DB1件は標準ポートで自動承認)
09:02  データ等級がpersonal-creditのため決裁を自動上申
       (リーダー + 情報保護レビュー — スキャン結果と依存グラフを自動添付)
14:30  情報保護チーム承認 (レビューに必要な情報がすべて添付済みで迅速)
14:31  本番ネームスペースのプロビジョニング、シークレットはボールト参照で自動注入
16:00  初回本番デプロイ完了 — 作成からデプロイまで全証跡が自動保存
開発者の実感: 「午前に作って午後にリリースした」

重要なのは「決裁が消えたわけではない」ことです。決裁は依然としてあります(情報保護チームの承認 14:30)。消えたのは申請書の作成、キュー待ち、情報の再収集、手動登載 — つまり決裁と決裁の間の摩擦です。

失敗パターン

よくある失敗を先に知っておけば、半分は避けられます。

  • **ポータルから作り始める。**バックエンド自動化なしにBackstage UIだけを被せると「きれいな申請書作成ツール」になります。テンプレート実行が実際のリソースを最後まで作り切る垂直スライス1本のほうが、画面10枚より価値があります。
  • **全チームを同時にオンボーディング。**パイロットチーム1~2つと深く協業してゴールデンパスを磨いてから拡散すべきです。生煮えのプラットフォームの第一印象は回復が困難です。
  • **ガバナンス合意なき自動化。**決裁簡素化をプラットフォームチームが独断で決めると、監査で全体がひっくり返ります。リスク等級マトリクスをセキュリティ・コンプライアンス組織と共同署名してから始めるべきです。
  • レガシー決裁システム連携の回避。「APIがないから」と決裁連携を先送りすれば、プラットフォームは永遠に半人前です。画面自動化(RPA)でも連携するほうがましです。
  • **プラットフォームチームのチケット処理班化。**セルフサービスではなく「プラットフォームチームに頼めばやってくれる」になれば、ボトルネックが1か所に集まっただけです。すべての機能はポータル・APIセルフサービスが基本であるべきです。
  • **測定なき航海。**導入前のリードタイムを測定しておかなければ、1年後に成果を証明できず、予算が切られます。

導入ロードマップ

段階期間(例)主要成果物
0. アライメント1~2か月セキュリティ・コンプライアンス組織とリスク等級マトリクス合意、パイロットチーム選定、現行リードタイム測定
1. 垂直スライス2~3か月テンプレート1本でリポジトリ~本番デプロイまで完全自動化 (決裁連携を含む)
2. カタログ2か月既存サービスの一括登載、人事連携の所有者、資産報告バッチ
3. 拡散3~6か月テンプレート3~5種へ拡大、パイロット外の本部オンボーディング、閉域網ミラーの安定化
4. ガバナンス深化継続未登載資産の検知、証跡の自動算出、スコアカードの定例報告

チェックリスト

ガバナンス

  • リスク等級マトリクスがセキュリティ・コンプライアンス組織と共同合意・署名されているか
  • 自動承認のポリシー審査結果が証跡として保存されているか
  • テンプレートのセキュアデフォルトをセキュリティチームが共同所有(CODEOWNERS)しているか

ゴールデンパス

  • テンプレート実行だけでリポジトリ・パイプライン・監視・カタログ登載が完結するか
  • データ等級に応じて暗号化・決裁ラインが自動分岐するか
  • セキュリティスキャン(SAST/SCA/イメージ)と署名がパイプラインに既定で含まれるか

カタログ

  • 所有者が人事システムと同期され、退職・異動時に自動更新されるか
  • 監督報告項目(資産ID、等級、承認証跡)がメタデータとして保存されているか
  • 未登載資産(カタログにないランタイムワークロード)の検知が動作するか

閉域網運用

  • npm・イメージ・プラグインのミラーと搬入手続きが標準化されているか
  • ビルドが社内ミラーだけで再現可能か (外部依存ゼロ)
  • Backstageアップグレードの周期と手順が計画されているか

測定

  • 導入前の基準線(リードタイム、デプロイ頻度)が記録されているか
  • DORA + 規制指標のスコアカードが定例報告されているか
  • 指標をチーム評価に使わないという原則が公表されているか

おわりに

銀行でプラットフォームエンジニアリングをやるということは、結局2つの世界の翻訳者になることです。開発者には「3週間の手続きが1日に縮む体験」として、セキュリティチームには「点検対象が300から5に減る構造」として、経営陣には「コンプライアンスコストが自動化に転換される投資」として — 同じプラットフォームが3つの言語で説明されなければなりません。

Backstageとガバナンスの結婚は比喩ではなく実装課題です。テンプレートに規制要件を入れ、Scaffolderに決裁をつなぎ、カタログを資産台帳にする仕事。華やかではありませんが、この配管工事が終わった組織では、規制産業の開発スピードに関する通念が崩れるのを目にすることになるでしょう。

参考資料