チャネル オンボーディング — システム管理者編¶
対象読者: automedia 開発者 (システム管理者)。メディア運営者向けの手順は メディア運営者編 を参照。
新規テナントを立ち上げる際に管理者が 1 度だけ実施する bootstrap 作業 をまとめる。bootstrap では SNS キーの初回投入も管理者が行う(鍵取得が運営者にしかできない場合は、運営者に依頼して安全な経路で受領し管理者が投入する)。完了後、運営者は メディア運営者編 に従ってチャネル運用を行い、以降のキーローテーションはセルフサービスで実施できる(LINE / Backlog / HubSpot。GitHub は _meta 横断のため管理者管理)。
0. 共通方針¶
認証情報の保管場所¶
| 保管先 | 用途 |
|---|---|
AWS Secrets Manager (/automedia/<tenant>/<provider>) |
runtime トークンの SoT。各 Lambda が IAM ロール経由で read |
/automedia/_meta/github |
sync Lambda が使う GitHub Webhook secret + PAT (テナント横断) |
| Backlog Wiki (TTRTAGSPIN) | アカウント・アプリの「在処」のみ記載。秘匿情報そのものは置かない。管理画面パスワード等の人間用ログインは Wiki が SoT |
詳細は セキュリティ・シークレット を参照。
ローテーション方針¶
- 既定: 90 日ごと
- ローテーション実施は Backlog Wiki に履歴を残す
- CloudWatch Alarm で期限通知 (Phase 1c で実装予定)
bootstrap 時点では placeholder 値を入れる¶
各 provider の secret は最初 placeholder 値 (_placeholder prefix) で作成しておく。Lambda 側は placeholder を検知して該当 provider 処理を no-op にする (webhook-line で実装済パターン)。本値の 初回投入は bootstrap 時に管理者が put-secret-value で行う(鍵取得が運営者依存なら安全な経路で受領)。投入後のローテーションは運営者が /automedia-secret-set skill でセルフサービス実施できる(LINE / Backlog / HubSpot)。
前提要件 (AWS アカウント単位 / 初回のみ) — IdC を 2 箇所設定 (#188)¶
新規 AWS アカウントで automedia を立ち上げる際に アカウント全体で 1 回だけ 実施する。 テナント追加や運営者追加のたびには不要。
前提 1: "Send email OTP" を有効化 (パスワード設定経路を開通)¶
identitystore create-user で作成したユーザーは password 無し状態で、AWS の自動 Welcome
メールが届かない。この設定を ON にすると、ユーザーが初回サインインを試みたタイミングで
AWS が verification メールを自動送付し、運営者は link から初期パスワード設定を完了できる
(AWS docs)。
- IAM Identity Center Console を開く
- 左メニュー Settings > Authentication タブ
- Standard authentication セクションの Configure をクリック
- Send email OTP チェックボックスを ON
- Save をクリック (Status が
Disabled→Enabledに変わることを確認)
前提 2: MFA を「サインイン時に登録するよう要求」に設定 (MFA 強制)¶
automedia は本番テナント secret に触れる運用なので、運営者は全員 MFA 必須とする。 パスワード設定直後に MFA 登録画面に遷移させる:
- Settings > Authentication タブ > Multi-factor authentication > Configure
- 登録された MFA デバイスをユーザーが持っていない場合: 「サインイン時に MFA デバイスを登録するよう要求する」 を選択 (デフォルトは「ユーザーをサインインを許可する」= MFA 未登録のままログイン可能)
- その他の設定は既定のままで OK:
- MFA のプロンプトをユーザーに表示: コンテキスト対応
- 認証タイプ: セキュリティキー / Authenticator アプリケーション
- MFA デバイスを管理できるユーザー: ユーザー自身も管理可
- 変更を保存 をクリック
API / CLI からの設定変更可否¶
両設定とも公開 API / CLI では設定変更も状態確認も できない (Console 専用)。 公開 API が無い理由は AWS re:Post の公式回答 を参照。
前提 1 が未有効だと
/automedia-operator-onboard自体は成功するが、運営者は SSO portal で 初期パスワード設定にたどり着けず、管理者が Console から one-time password を発行する フォールバック (§9-2) が毎回必要になる。 前提 2 を「サインインを許可する」のままにすると、運営者は MFA 未登録のままログインでき、 後で Security メニューから手動登録する形になる (セキュリティ的に非推奨)。
1. placeholder secret の作成¶
# LINE
aws --profile spindd-admin secretsmanager create-secret \
--name /automedia/<tenant>/line \
--secret-string '{
"channel_id": "_placeholder",
"channel_secret": "_placeholder",
"access_token": "_placeholder"
}' --region ap-northeast-1
# HubSpot
aws --profile spindd-admin secretsmanager create-secret \
--name /automedia/<tenant>/hubspot \
--secret-string '{
"access_token": "_placeholder",
"portal_id": "_placeholder"
}' --region ap-northeast-1
# Backlog (space_key と webhook_secret は管理者が値を投入、api_key は placeholder)
WEBHOOK_SECRET=$(python3 -c 'import secrets; print(secrets.token_hex(32))')
aws --profile spindd-admin secretsmanager create-secret \
--name /automedia/<tenant>/backlog \
--secret-string "$(jq -n --arg ws "$WEBHOOK_SECRET" '{
space_key: "spindd",
api_key: "_placeholder",
webhook_secret: $ws
}')" --region ap-northeast-1
expires_attag を付けるとsecret-watchLambda (#79) が週次で期限を監視する。新規作成時に仮の期限 (例: 90 日後) を付けておく。
2. IAM Permission Set 整備¶
aws/tofu/iam-identity-center.tf に当該テナント用の Permission Set を追加。詳細は クレデンシャル配布: per-tenant Permission Set を参照。
resource "aws_ssoadmin_permission_set" "tenant_operator_<tenant>" {
name = "TenantOperator-<tenant>"
instance_arn = "arn:aws:sso:::instance/ssoins-18083f7232cea59f"
session_duration = "PT8H"
}
# + inline_policy で GetSecretValue / PutSecretValue / execute-api を per-tenant ARN 限定で許可
# + 該当 SSO ユーザーへの account_assignment
tofu apply 後、運営者が aws sso login --profile spindd-<tenant> でログインできる状態になる。
3. Backlog Webhook 登録 (管理者側)¶
space_key / webhook_secret は テナント全体で 1 度だけ設定する値 で、運営者は触らない。
# 上で生成した WEBHOOK_SECRET を URL path に埋め込む
WEBHOOK_URL="https://api.automedia.spin-dd.com/backlog/webhook/${WEBHOOK_SECRET}"
Backlog API もしくは UI で Webhook 登録:
- URL:
${WEBHOOK_URL} - イベント: 課題追加 / 課題更新 / コメント追加
4. GitHub theme repo Webhook 登録¶
# /automedia/_meta/github の webhook_secret を取得
WEBHOOK_SECRET=$(aws --profile spindd-admin secretsmanager get-secret-value \
--secret-id /automedia/_meta/github --query SecretString --output text \
| jq -r .webhook_secret)
# theme repo に登録
gh api repos/spin-dd/<tenant>-hubspot-theme/hooks --method POST -F config[url]=https://api.automedia.spin-dd.com/github/webhook -F config[content_type]=application/json -F config[secret]="${WEBHOOK_SECRET}" -F events[]=push
5. tenants.json を仮値で追加¶
aws/tenants/_meta/tenants.json:
{
"by_line_channel": {
"_placeholder_<tenant>": "<tenant>"
},
"by_backlog_category": {
"<category>": "<tenant>"
},
"by_github_repo": {
"spin-dd/<tenant>-hubspot-theme": "<tenant>"
}
}
LINE の channel_id は運営者が LINE Developers Console で発行後に値が確定するので、ここでは仮値で進めて後で正式値に修正する。
PR + tofu apply。
6. project.json の雛形を作成¶
aws/tenants/<tenant>/project.json:
{
"tenant": "<tenant>",
"aws": {
"profile": "spindd-<tenant>"
},
"channels": {
"line": { "enabled": false },
"hubspot": { "enabled": false }
},
"ai": {
"model": "claude-opus-4-7"
}
}
enabled: false で開始し、運営者の credential 投入完了後に true へ昇格させる (HubSpot は blog_id / author_id / author_name 取得後)。
7. welcome.json の雛形を作成¶
aws/tenants/<tenant>/templates/line/welcome.json:
運営者が文面を仕上げる前提で雛形のみ用意する。
8. tofu apply で確定¶
これで Lambda / API Gateway / Schedule / Permission Set が反映される。
9. 運営者への引き継ぎ案内¶
全体フロー (BPMN swim lane / #188)¶
下図は §9 の 運営者ごと に発生するオンボーディング業務を BPMN 2.0 のスイムレーンで 表したもの。管理者・AWS (IdC + SES)・運営者の責務境界とフォールバック分岐 (verification メール不達時の OTP 発行) を 1 枚で確認できる。

本フローを始める前に: AWS アカウント単位の前提要件 (IdC 2 箇所設定) を 1 回だけ済ませておくこと。済んでいれば運営者追加ごとには不要。
9-1. SSO ユーザーの登録 + 招待メール送信¶
Identity Center 側のユーザー作成・Permission Set 割り当て・招待メール送信は管理者 skill
/automedia-operator-onboard (#115 / #174 / #188) を使う。本章 §2 (IAM Permission Set
整備) で OpenTofu の account_assignment まで終わっていれば、以下 1 コマンドで完了する:
# dry-run で計画確認
node "$CLAUDE_SKILL_DIR/operator-onboard.mjs" \
--tenant <tenant> --operator-email <user@example.com> --operator-name "<表示名>"
# 問題なければ user 作成 + 招待メール送信を 1 コマンドで
node "$CLAUDE_SKILL_DIR/operator-onboard.mjs" \
--tenant <tenant> --operator-email <user@example.com> --operator-name "<表示名>" \
--send-invite --apply
招待メールには次が含まれる (send-operator-invite.mjs):
- 初期パスワード設定の手順 (SSO start URL → UserName のみ入力 → 届く verification メール 経由で password + MFA 登録)
~/.aws/configsnippet- 運営者ハンドブック URL
9-2. (フォールバック) verification メールが届かない場合: one-time password を発行¶
§9-0 を未設定の環境、または運営者環境のメール受信に問題があり verification メールが 届かない場合は、管理者が Console から one-time password (OTP) を発行する:
- IAM Identity Center Console > Users
- 該当運営者の UserName をクリック
- Reset password ボタン
- Generate a one-time password and share the password with the user を選択
- 表示された AWS access portal URL + password をコピー (画面を閉じると再表示不可)
- 運営者へ別経路 (Slack DM / 安全な方法) で渡す
- 運営者は SSO start URL に UserName + OTP でサインイン → 初期パスワード設定 + MFA 登録
OTP の有効期限は AWS 側で 7 日。期限切れの場合は同手順で再発行する。 CloudTrail に admin の
ResetPasswordaction が記録される。
9-3. 引き継ぎ時に運営者へ共有するもの¶
9-3. 引き継ぎ時に運営者へ共有するもの¶
招待メール (§9-1) を送信していれば本文に同梱済み。別途 Slack / メールでも案内する場合は:
- SSO start URL (例:
https://<spindd-domain>.awsapps.com/start) - 担当テナント名 (
<tenant>) - AWS profile 名 (
spindd-<tenant>) - 初期パスワード設定の手順 (招待メール本文 = §9-1 で送信済み)
- メディア運営者編 のリンク
以降は運営者がセルフサービスで進める。
10. 事後の値固定 (運営者の作業完了後)¶
運営者が LINE / HubSpot の credential 投入を完了したら、管理者は以下を実施:
- LINE
channel_idが確定したらtenants.jsonのby_line_channelを正式値に修正して PR +tofu apply - HubSpot
blog_id/author_id/author_nameを取得しproject.json > channels.hubspotに投入、enabled: trueで PR +tofu apply - E2E テスト課題で配信確認
HubSpot 値の取得:
ACCESS_TOKEN=$(aws --profile spindd-admin secretsmanager get-secret-value \
--secret-id /automedia/<tenant>/hubspot --query SecretString --output text | jq -r .access_token)
# CMS Blog の contentGroupId
curl -H "authorization: Bearer ${ACCESS_TOKEN}" \
https://api.hubapi.com/cms/v3/blog-settings/settings
# Blog Author の id
curl -H "authorization: Bearer ${ACCESS_TOKEN}" \
https://api.hubapi.com/cms/v3/blogs/authors
11. 運営者引き継ぎの自動化 (将来計画)¶
§9 の引き継ぎ作業 (Identity Center ユーザー登録 / Permission Set assignment / SSO 情報の伝達 / 運営者編 URL の案内) は 段階的にシステム化 する。実装は別 Issue で切り出して進める。
Phase 1: welcome メッセージ生成スクリプト (#115, 実装済み)¶
当初は OpenTofu output 化を想定していたが、SSO アクセスポータル URL (start URL) は
aws_ssoadmin_instances data source から取得できず tofu 変数のハードコードが必要になる。
代わりに 値を実行時に自動解決する生成スクリプト aws/tools/operator-welcome.mjs
(依存ゼロ Node + aws CLI) で実装した。
node aws/tools/operator-welcome.mjs --tenant bato
# カスタムサブドメイン時のみ start URL を上書き:
node aws/tools/operator-welcome.mjs --tenant bato --start-url https://acme.awsapps.com/start
スクリプトは以下を自動解決し、運営者がそのまま使える welcome テキストを出力する:
- Account ID:
aws sts get-caller-identity - Identity Store ID:
aws sso-admin list-instances(IdC home region) - start URL: identity store id からデフォルトポータル URL
https://<identity-store-id>.awsapps.com/startを導出 (--start-urlで上書き可) - Permission Set 名:
TenantOperator-<tenant>(#112)
出力には ~/.aws/config 用 snippet ([sso-session] + [profile spindd-<tenant>]) +
SSO ログイン手順 + テーマリポ初期化 (npx github:spin-dd/automedia init) + ドキュメント URL
が含まれる。URL / Account ID / Role 名はすべて API から展開するため手入力ミスが起きない。
出力 snippet はそのまま運営者の /automedia-aws-config-setup skill (#113) に貼り付けられる。
管理者は出力を Slack / メールで運営者に渡すだけでよい。
Phase 2.5: 招待メールの SES 自動送信 (#174, 実装済み)¶
AWS Identity Center にはプログラマブルな「招待メール送信 API」が無いため (CreateUser
は招待メールを自動送信しない)、Phase 2 までだと管理者が Console で「Reset password」を
手動クリックする必要があった。これを SES (sesv2 send-email) での自前送信に置き換える。
新規スクリプト aws/tools/send-operator-invite.mjs および operator-onboard.mjs の
--send-invite オプションで送信。本文には次を含める:
- 担当テナント / 宛先 UserName
- 初期パスワード設定の手順 (SSO start URL → UserName 入力 → AWS から届く "Verify your email address" メール経由でパスワード設定 + MFA 登録) — #188 で修正
~/.aws/configsnippet (operator-welcome.mjsを再利用、HTML は<pre>で整形維持)- 運営者ハンドブックの URL
前提 (#188): IdC の "Send email OTP" 設定が有効化済みであること。 Console > Settings > Authentication > Standard authentication > Configure > Send email OTP を ON。API/CLI で作成したユーザーは password 無し状態のため、この 設定を有効化していないと初回サインイン時に verification メールが届かず、ユーザーは 初期パスワード設定にたどり着けない (「Forgot password?」は既存ユーザー再設定用で MFA 検証を要求するため、新規 API ユーザーは進めない)。未設定環境では、管理者が Users > 該当ユーザー > Reset password > Generate a one-time password で OTP を 発行して運営者へ別経路で渡すフォールバックが必要。 参照: https://docs.aws.amazon.com/singlesignon/latest/userguide/userswithoutpwd.html
# 単独実行 (dry-run でプレビュー)
node aws/tools/send-operator-invite.mjs \
--tenant bato --operator-email hanako@example.com --operator-name "花子"
# ↑ --from 既定 = noreply@automedia.spin-dd.com
# operator-onboard と同時実行 (user 作成と招待メール送信を 1 コマンドで)
node "$CLAUDE_SKILL_DIR/operator-onboard.mjs" \
--tenant bato --operator-email hanako@example.com --operator-name "花子" \
--send-invite --apply
前提 (Tofu で自動セットアップ済 / #174):
automedia.spin-dd.comzone が Route 53 に存在し、親spin-dd.comから NS 委譲済- SES Domain identity
automedia.spin-dd.comが verified、Easy DKIM 有効 - Custom MAIL FROM =
mail.automedia.spin-dd.com(SPF alignment 用 MX/TXT) - DMARC TXT (
_dmarc.automedia.spin-dd.com) がp=noneで監視中 - → SPF / DKIM / DMARC のすべてが pass し、Gmail / Outlook 等で迷惑メール判定されにくい
SES が sandbox モード (ProductionAccessEnabled=false) の場合は宛先側も verified が必要。
本番運用化は AWS Console > SES > Account dashboard で production access を申請する。
呼び出し元 IAM に ses:SendEmail (sesv2) の許可が必要。
Phase 2: 管理者 skill /automedia-operator-onboard (#115, 実装済み)¶
管理者が 1 コマンドで運営者追加 を完結できる管理者専用 skill
(.claude/skills/automedia-operator-onboard、依存ゼロ Node + aws CLI)。
# まず dry-run (既定): 計画 (user/assignment の create/exists) + welcome を確認
node "$CLAUDE_SKILL_DIR/operator-onboard.mjs" \
--tenant bato --operator-email hanako@example.com --operator-name "花子"
# 問題なければ --apply で実行
node "$CLAUDE_SKILL_DIR/operator-onboard.mjs" \
--tenant bato --operator-email hanako@example.com --operator-name "花子" --apply
挙動 (冪等):
- Identity Store にユーザーが居なければ CreateUser、居れば再利用
- TenantOperator-<tenant> Permission Set に CreateAccountAssignment (割当済みは skip)
- operator-welcome.mjs (Phase 1) で welcome 生成、--notify slack で Slack 投稿 (任意)
- CreateUser / CreateAccountAssignment は CloudTrail に記録 (監査)
設計上の要点:
| 項目 | 内容 |
|---|---|
| 実行モデル | 既定 dry-run、--apply で実 API。ID 作成の誤実行を防ぐ |
| 権限 | 呼び出し元 (管理者の SSO 認証) を使用。必要 action は SKILL.md / 下記に明記。AdministratorAccess 相当ならそのまま満たす (tofu でのロール新設はしない) |
| 配布 | 管理者専用のため SKILL.md に distribute: false。npx ... init/upgrade の配布対象から除外される (テーマリポへは配らない) |
| Slack | --notify slack + SLACK_WEBHOOK_URL env (未設定なら skip) |
必要 IAM action (管理者の認証情報側):
sso-admin:ListInstances / ListPermissionSets / DescribePermissionSet /
ListAccountAssignments / CreateAccountAssignment /
DescribeAccountAssignmentCreationStatus、identitystore:GetUserId / CreateUser、
sts:GetCallerIdentity。
Phase 3 以降の発展案 (参考)¶
- Backlog Wiki に運営者向けオンボーディング page を自動生成 (
spindd.backlog.com/wiki/TTRTAGSPIN/Operators/<tenant>) - テナント PR マージで GitHub Actions が起動して
tofu apply+ 通知まで一気通貫 - SES でメール直接送信 (運営者のメールアドレスが既知の前提)
これらは Phase 1c / Phase 4 (マルチテナント Bootstrap 自動化、ロードマップ) のスコープに含める。
管理者チェックリスト¶
AWS アカウント単位 (初回のみ / 1 回だけ)¶
- IdC Console > Settings > Authentication > Standard authentication で Send email OTP を有効化 (前提 1)
- IdC Console > Settings > Authentication > Multi-factor authentication で「サインイン時に MFA デバイスを登録するよう要求する」を選択 (前提 2)
テナント追加ごと (1 テナント = 1 回)¶
scaffold 部分(tenants.json / project.json / welcome template /
var.tenants)はnode aws/tools/bootstrap-tenant.mjs --tenant <t> [--backlog-category <名>] --applyでまとめて生成できる(#84、冪等)。残りの手作業は以下。
-
/automedia/<tenant>/line/hubspot/backlogを placeholder でcreate-secret -
aws/tofu/iam-identity-center.tfにTenantOperator-<tenant>Permission Set 追加 + 運営者を assignment - Backlog の
space_key/webhook_secretを投入、Webhook 登録 (register-saas.mjs --saas backlog --project-key <KEY> --apply) - GitHub theme repo の Webhook 登録 (
GITHUB_PAT=... register-saas.mjs --saas github --apply) - LINE webhook endpoint 登録 (
register-saas.mjs --saas line --apply) / HubSpot Private App 作成 (register-saas.mjs --saas hubspotで手順表示) -
aws/tenants/_meta/tenants.jsonにby_line_channel(仮値) /by_backlog_category/by_github_repoを追加して PR -
aws/tenants/<tenant>/project.json雛形を作成 (enabled: falseで開始) -
aws/tenants/<tenant>/templates/line/welcome.json雛形を作成 -
tofu apply
運営者追加ごと (1 運営者 = 1 回)¶
-
/automedia-operator-onboard --send-invite --applyで運営者を Identity Store に作成 + 招待メール送信 (§9-1) - 運営者へ SSO 情報 + メディア運営者編 のリンクを案内 (招待メールに同梱済)
- (運営者作業完了後)
tenants.jsonの LINEchannel_id正式値修正 - (運営者作業完了後)
project.json > channels.hubspotにblog_id/author_id/author_name投入 +enabled: true - E2E テスト課題で配信確認