mcpField
S
saas-security-posture

saas-security-posture

github.com/bagelholeセキュリティ1.2k315 回インストール23 週間前に更新
リポジトリ

saas-security-posture について

スタートアップ向けの SaaS セキュリティ態勢管理スキルです。SaaS の棚卸し、設定強化、リスク確認をコマンド例で扱い、コンプライアンス準備やインシデント対応、シャドー IT の発見に役立ちます。

主な機能

  1. 01SaaS ツールと OAuth 付与の棚卸し
  2. 02GitHub、Slack、Google Workspace、AWS の強化
  3. 03リスクの高い OAuth 付与の特定と取り消し
  4. 04MFA、SSO、最小権限の設定
  5. 05DNS とログによるシャドー IT の検出

活用シーン

  1. 01SOC 2 監査向けのセキュリティ統制証跡の収集
  2. 02不審なサードパーティアプリの権限確認
  3. 03未承認の SaaS ツールの発見と管理
  4. 04フィッシングや認証情報流出後のアカウント強化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill saas-security-posture

インストール後、Claude Code で/saas-security-postureを入力して読み込まれたか確認します。

詳細

スタートアップ向け SaaS セキュリティ態勢管理

実践的なコマンドベースの強化策で、会社が利用するすべての SaaS ツールを保護します。

1. このスキルを使うタイミング

  • SOC 2 の準備 — 監査担当者は MFA、アクセス制御、OAuth ガバナンスの証拠を求めます。
  • 不審な OAuth アプリ — 従業員が広範なスコープを持つサードパーティ製アプリを承認しました。
  • SaaS の乱立 — チームが会社のメールアドレスでツールに登録し、誰もそれを追跡していません。
  • インシデント後の強化 — フィッシングや認証情報の漏えい後に、あらゆる攻撃対象を強化します。

2. SaaS インベントリ監査

Google Workspace — OAuth の許可
gam all users show tokens > oauth_tokens_audit.csv
GitHub — インストール済みアプリ
gh api /orgs/{ORG}/installations --paginate \
  --jq '.installations[] | {app: .app_slug, permissions: .permissions, created: .created_at}'
gh api /orgs/{ORG}/credential-authorizations --paginate \
  --jq '.[] | {login: .login, credential_type: .credential_type}'
Slack — 承認済みおよび保留中のアプリ
curl -s -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  "https://slack.com/api/admin.apps.approved.list" | jq '.approved_apps[] | {name: .app.name, id: .app.id}'
curl -s -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  "https://slack.com/api/admin.apps.requests.list" | jq '.app_requests[]'
AWS — IAM 認証情報レポート
aws iam generate-credential-report
aws iam get-credential-report --output text --query 'Content' | base64 -d > iam_credential_report.csv
インベントリのマスターテンプレート
tools:
  - name: Google Workspace
    owner: [email protected]
    sso: true
    mfa: enforced
  - name: GitHub Enterprise
    owner: [email protected]
    sso: true
    mfa: enforced
  - name: Slack Business+
    owner: [email protected]
    sso: true
    app_approval: required
  - name: AWS Organizations
    owner: [email protected]
    sso: true
    scp_enforced: true

3. GitHub のセキュリティ強化

# Enforce 2FA and find non-compliant members
gh api -X PATCH /orgs/{ORG} -f two_factor_requirement_enabled=true
gh api /orgs/{ORG}/members?filter=2fa_disabled --paginate --jq '.[].login'

# Verify SAML SSO identities
gh api /orgs/{ORG}/credential-authorizations --paginate \
  --jq '.[] | {login: .login, saml_name_id: .saml_name_id}'

# Add IP allow list entry
gh api -X POST /orgs/{ORG}/ip-allow-list \
  -f allow_list_value="203.0.113.0/24" -f name="Office VPN" -F is_active=true

# Branch protection on main
gh api -X PUT /repos/{ORG}/{REPO}/branches/main/protection \
  -H "Accept: application/vnd.github+json" --input - <<'EOF'
{
  "required_status_checks": {"strict": true, "contexts": ["ci/build","ci/test"]},
  "enforce_admins": true,
  "required_pull_request_reviews": {
    "required_approving_review_count": 2,
    "dismiss_stale_reviews": true,
    "require_code_owner_reviews": true
  },
  "restrictions": null,
  "allow_force_pushes": false,
  "allow_deletions": false
}
EOF

# Audit PATs and revoke stale tokens
gh api /orgs/{ORG}/personal-access-tokens --paginate \
  --jq '.[] | {owner: .owner.login, name: .token_name, expires: .token_expires_at}'
gh api -X DELETE /orgs/{ORG}/personal-access-tokens/{PAT_ID}

# Audit deploy keys and webhooks
for repo in $(gh repo list {ORG} --limit 500 --json name -q '.[].name'); do
  gh api /repos/{ORG}/${repo}/keys --jq '.[] | {title: .title, read_only: .read_only}'
done
gh api /orgs/{ORG}/hooks --jq '.[] | {url: .config.url, events: .events, active: .active}'

4. Slack のセキュリティ

# Require app approval
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.apps.config.set" -d '{"app_approval_enabled": true}'

# Set workspace to invite-only
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.teams.settings.setDiscoverability" \
  -d '{"team_id": "T0XXXXXXX", "discoverability": "invite_only"}'

# Force re-authentication every 24 hours
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.teams.settings.setSessionDuration" \
  -d '{"team_id": "T0XXXXXXX", "session_duration": 86400}'

# Set message retention to 1 year
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.teams.settings.setRetentionPolicy" \
  -d '{"team_id": "T0XXXXXXX", "retention_type": "all", "retention_duration": 365}'

# Audit Slack Connect shared channels
curl -s -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  "https://slack.com/api/admin.conversations.search?search_channel_types=connect" \
  | jq '.conversations[] | {name: .name, is_ext_shared: .is_ext_shared}'

5. Google Workspace の強化

# Enforce 2-Step Verification and strong passwords
gam update org "/" settings 2sv enforced
gam update org "/" settings password_length 14

# Block all third-party OAuth apps, then whitelist specific ones
gam update org "/" settings oauth_access block_all
gam update org "/" settings oauth_access whitelist client_id:APP_CLIENT_ID_1

# Disable external Drive sharing and file transfers
gam update org "/" settings drive sharing_outside_domain off
gam update org "/" settings drive transfer_to_personal off
gam update org "/" settings groups external_members off

# Verify email authentication records
dig TXT company.com | grep "v=spf1"
dig TXT google._domainkey.company.com
dig TXT _dmarc.company.com
# Expected: v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100

# Mobile device management
gam update org "/" settings mobile management advanced
gam update org "/" settings mobile screen_lock required
gam update org "/" settings mobile encryption required
gam update mobile ${DEVICE_ID} action wipe   # compromised device

6. AWS アカウントのセキュリティ

# Root account lockdown — verify MFA, remove access keys
aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled'
aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'

# SSO permission set with least privilege
aws sso-admin create-permission-set --instance-arn "${SSO_INSTANCE_ARN}" \
  --name "DeveloperAccess" --session-duration "PT8H"
aws sso-admin attach-managed-policy-to-permission-set \
  --instance-arn "${SSO_INSTANCE_ARN}" --permission-set-arn "${PERMISSION_SET_ARN}" \
  --managed-policy-arn "arn:aws:iam::aws:policy/ReadOnlyAccess"
サービスコントロールポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {"Sid": "DenyRootActions", "Effect": "Deny", "Action": "*", "Resource": "*",
     "Condition": {"StringLike": {"aws:PrincipalArn": "arn:aws:iam::*:root"}}},
    {"Sid": "DenyLeaveOrg", "Effect": "Deny",
     "Action": "organizations:LeaveOrganization", "Resource": "*"}
  ]
}
aws organizations create-policy --name "DenyRootActions" \
  --type SERVICE_CONTROL_POLICY --content file://deny-root-actions.json
aws organizations attach-policy --policy-id "${POLICY_ID}" --target-id "${ORG_ROOT_ID}"

# Organization-wide CloudTrail
aws cloudtrail create-trail --name org-security-trail \
  --s3-bucket-name company-cloudtrail-logs \
  --is-multi-region-trail --is-organization-trail --enable-log-file-validation
aws cloudtrail start-logging --name org-security-trail

7. OAuth アプリのレビュー

高リスクの許可を特定する
# Google — find apps with dangerous scopes
gam all users show tokens | grep -E "(drive|gmail|admin)" > high_risk_oauth.txt

# GitHub — find apps with write access
gh api /orgs/{ORG}/installations --paginate \
  --jq '.installations[] | select(.permissions.contents == "write") | {app: .app_slug}'
危険な許可を取り消す
gam user [email protected] delete token clientid APP_CLIENT_ID  # single app
gam user [email protected] delete tokens                        # all apps
gh api -X DELETE /orgs/{ORG}/installations/{INSTALLATION_ID}           # GitHub app
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.apps.uninstall" -d '{"app_id": "A0XXXXXXX"}'
スコープのリスク分類
CRITICAL — revoke unless justified:
  Google: mail.google.com, admin.directory.user | GitHub: admin:org, repo | Slack: admin
HIGH — review carefully:
  Google: googleapis.com/auth/drive | GitHub: contents:write | Slack: channels:read
LOW — generally safe:
  Google: userinfo.email | GitHub: read:org | Slack: identity.basic

8. 管理者アカウントの保護

# Dedicated admin account in Google Workspace
gam create user [email protected] firstname "John (Admin)" lastname "Doe" \
  password "$(openssl rand -base64 32)" org "/Admins"
gam update user [email protected] admin on

# Require hardware security keys for the Admins OU
gam update org "/Admins" settings 2sv security_key_only

# AWS MFA enforcement policy
cat <<'EOF' > enforce-mfa-policy.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "DenyUnlessMFA", "Effect": "Deny",
    "NotAction": ["iam:CreateVirtualMFADevice","iam:EnableMFADevice",
                  "iam:GetUser","iam:ListMFADevices","sts:GetSessionToken"],
    "Resource": "*",
    "Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}}
  }]
}
EOF
aws iam create-policy --policy-name EnforceMFA --policy-document file://enforce-mfa-policy.json

# Break-glass account for SSO outages
BREAK_GLASS_PW=$(openssl rand -base64 48)
gam create user [email protected] firstname "Break" lastname "Glass" \
  password "${BREAK_GLASS_PW}" org "/Admins" admin on
# Store password in a sealed envelope in a physical safe
# After every use: rotate password, re-seal, log the incident

9. データ損失防止

# Google Drive — block external sharing and restrict viewers
gam update org "/" settings drive sharing_outside_domain off
gam update org "/" settings drive disable_download_print_copy_for_viewers on

# GitHub — enable secret scanning and push protection org-wide
gh api -X PATCH /orgs/{ORG} -f security_product=secret_scanning -f enablement=enable_all
gh api -X PATCH /orgs/{ORG} -f security_product=secret_scanning_push_protection -f enablement=enable_all
gh api /orgs/{ORG}/secret-scanning/alerts --paginate \
  --jq '.[] | {repo: .repository.name, secret_type: .secret_type, state: .state}'

# Slack — restrict data export to org admins
curl -s -X POST -H "Authorization: Bearer ${SLACK_ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  "https://slack.com/api/admin.teams.settings.setExportRestrictions" \
  -d '{"team_id": "T0XXXXXXX", "export_type": "org_admins_only"}'

# AWS — block all public S3 access at account level
aws s3control put-public-access-block --account-id "${AWS_ACCOUNT_ID}" \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

10. シャドー IT の検出

DNS ベースの検出
SHADOW_IT_DOMAINS=("airtable.com" "notion.so" "trello.com" "asana.com"
  "monday.com" "clickup.com" "figma.com" "canva.com" "miro.com"
  "zapier.com" "dropbox.com" "box.com" "wetransfer.com")
for domain in "${SHADOW_IT_DOMAINS[@]}"; do
  count=$(grep -c "${domain}" /var/log/dns/query.log 2>/dev/null || echo "0")
  [ "${count}" -gt 0 ] && echo "DETECTED: ${domain} — ${count} queries"
done
Google Workspace のログイン監査
gam report login parameters app_name \
  start_time "2026-03-01T00:00:00Z" end_time "2026-03-24T23:59:59Z" > login_audit.csv
gam report token > token_usage_report.csv
プロキシログの分析
awk '{print $7}' /var/log/squid/access.log | sed 's|https\?://||;s|/.*||' \
  | sort | uniq -c | sort -rn | head -50 > top_domains.txt
comm -23 <(awk '{print $2}' top_domains.txt | sort) \
  <(yq '.tools[].domains[]' saas-inventory.yaml | sort) > unapproved.txt
アラートの自動化
cat <<'SCRIPT' > /usr/local/bin/shadow-it-check.sh
#!/usr/bin/env bash
set -euo pipefail
APPROVED="/etc/security/approved-saas-domains.txt"
YESTERDAY=$(date -d "yesterday" +%d-%b-%Y)
grep "${YESTERDAY}" /var/log/dns/query.log | awk '{print $4}' | sort -u > /tmp/today.txt
NEW=$(comm -23 /tmp/today.txt <(sort "${APPROVED}"))
[ -n "${NEW}" ] && mail -s "[ALERT] Shadow IT" [email protected] <<< "${NEW}"
SCRIPT
chmod +x /usr/local/bin/shadow-it-check.sh
echo "0 8 * * * root /usr/local/bin/shadow-it-check.sh" >> /etc/cron.d/shadow-it-check

クイックリファレンス — 優先度の高い 10 の対策

#アクション対象
1すべてのサービスで MFA/2FA を必須にするGoogle、GitHub、AWS、Slack
2IdP で SSO を有効にするすべてのツール
3OAuth の許可を監査して取り消すGoogle、GitHub
4Slack アプリの承認を必須にするSlack
5main ブランチの保護を有効にするGitHub
6シークレットスキャンとプッシュ保護を有効にするGitHub
7S3 バケットの公開をブロックするAWS
8組織全体で CloudTrail を有効にするAWS
9外部との Drive 共有を無効にするGoogle
10緊急用管理者アカウントを作成するGoogle、AWS

メンテナンスの頻度

毎週: OAuth の許可、シークレットスキャンのアラート、Slack アプリのキューを確認します。 毎月: AWS IAM レポートを確認し、サービスキーをローテーションし、管理者アカウントをレビューして、シャドー IT をスキャンします。 四半期ごと: SaaS インベントリ全体を更新し、OAuth の許可を整理し、緊急用アカウントをテストして、SCP を更新します。

コメント