关于 saas-security-posture
面向初创企业的 SaaS 安全态势管理技能,通过命令行示例指导 SaaS 盘点、权限加固和风险审查。覆盖 Google Workspace、GitHub、Slack 和 AWS 等服务,适用于合规准备、事件响应及发现未授权工具。
主要功能
- 01盘点 SaaS 工具和 OAuth 授权
- 02加固 GitHub、Slack、Google Workspace 和 AWS
- 03识别并撤销高风险 OAuth 授权
- 04配置 MFA、SSO 和最小权限
- 05通过 DNS 与日志发现影子 IT
适用场景
- 01为 SOC 2 审计收集安全控制证据
- 02审查可疑第三方应用授权
- 03排查并治理未经批准的 SaaS 工具
- 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 |
| 2 | 使用你的 IdP 启用 SSO | 所有工具 |
| 3 | 审计并撤销 OAuth 授权 | Google、GitHub |
| 4 | 要求审批 Slack 应用 | Slack |
| 5 | 为 main 设置分支保护 | GitHub |
| 6 | 启用密钥扫描和推送保护 | GitHub |
| 7 | 禁止 S3 存储桶公开访问 | AWS |
| 8 | 启用组织范围的 CloudTrail | AWS |
| 9 | 禁用外部 Drive 共享 | |
| 10 | 创建紧急备用管理员账户 | Google、AWS |
维护周期
每周: 审查 OAuth 授权、密钥扫描告警和 Slack 应用队列。
每月: 检查 AWS IAM 报告、轮换服务密钥、审查管理员账户、扫描影子 IT。
每季度: 全面更新 SaaS 清单、清理 OAuth 授权、测试紧急备用账户、更新 SCP。
评论
支持 Markdown