saas-security-posture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SaaS Security Posture Management for Startups

初创企业SaaS安全态势管理

Secure every SaaS tool your company relies on with practical, command-driven hardening.
通过实用的命令驱动型强化方案,保护公司依赖的每一款SaaS工具。

1. When to Use This Skill

1. 何时使用此技能

  • SOC 2 preparation — auditors need evidence of MFA, access controls, and OAuth governance.
  • Suspicious OAuth app — an employee authorized a third-party app with broad scopes.
  • SaaS sprawl — teams sign up for tools with company email and nobody tracks them.
  • Post-incident hardening — after phishing or credential leaks, tighten every surface.
  • SOC 2 合规准备 — 审计人员需要MFA、访问控制和OAuth治理的相关证据。
  • 可疑OAuth应用 — 员工授权了一个权限范围广泛的第三方应用。
  • SaaS工具蔓延 — 团队使用公司邮箱注册工具,但无人追踪管理。
  • 事件后强化 — 遭遇钓鱼攻击或凭证泄露后,全面收紧安全防护。

2. SaaS Inventory Audit

2. SaaS资产审计

Google Workspace — OAuth Grants

Google Workspace — OAuth授权

bash
gam all users show tokens > oauth_tokens_audit.csv
bash
gam all users show tokens > oauth_tokens_audit.csv

GitHub — Installed Apps

GitHub — 已安装应用

bash
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}'
bash
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 — Approved and Pending Apps

Slack — 已批准和待审批应用

bash
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[]'
bash
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 Credential Report

AWS — IAM凭证报告

bash
aws iam generate-credential-report
aws iam get-credential-report --output text --query 'Content' | base64 -d > iam_credential_report.csv
bash
aws iam generate-credential-report
aws iam get-credential-report --output text --query 'Content' | base64 -d > iam_credential_report.csv

Master Inventory Template

主资产清单模板

yaml
tools:
  - name: Google Workspace
    owner: it@company.com
    sso: true
    mfa: enforced
  - name: GitHub Enterprise
    owner: engineering@company.com
    sso: true
    mfa: enforced
  - name: Slack Business+
    owner: it@company.com
    sso: true
    app_approval: required
  - name: AWS Organizations
    owner: platform@company.com
    sso: true
    scp_enforced: true

yaml
tools:
  - name: Google Workspace
    owner: it@company.com
    sso: true
    mfa: enforced
  - name: GitHub Enterprise
    owner: engineering@company.com
    sso: true
    mfa: enforced
  - name: Slack Business+
    owner: it@company.com
    sso: true
    app_approval: required
  - name: AWS Organizations
    owner: platform@company.com
    sso: true
    scp_enforced: true

3. GitHub Security Hardening

3. GitHub安全强化

bash
undefined
bash
undefined

Enforce 2FA and find non-compliant members

强制启用2FA并找出不合规成员

gh api -X PATCH /orgs/{ORG} -f two_factor_requirement_enabled=true gh api /orgs/{ORG}/members?filter=2fa_disabled --paginate --jq '.[].login'
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

验证SAML SSO身份

gh api /orgs/{ORG}/credential-authorizations --paginate
--jq '.[] | {login: .login, saml_name_id: .saml_name_id}'
gh api /orgs/{ORG}/credential-authorizations --paginate
--jq '.[] | {login: .login, saml_name_id: .saml_name_id}'

Add IP allow list entry

添加IP允许列表条目

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
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
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

审计PAT并撤销过期令牌

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}
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

审计部署密钥和Webhook

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}'

---
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 Security

4. Slack安全配置

bash
undefined
bash
undefined

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}'
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"}'
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

强制每24小时重新认证

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}'
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

设置消息保留时长为1年

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}'
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

审计Slack Connect共享频道

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}'

---
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 Hardening

5. Google Workspace安全强化

bash
undefined
bash
undefined

Enforce 2-Step Verification and strong passwords

强制启用两步验证和强密码

gam update org "/" settings 2sv enforced gam update org "/" settings password_length 14
gam update org "/" settings 2sv enforced gam update org "/" settings password_length 14

Block all third-party OAuth apps, then whitelist specific ones

阻止所有第三方OAuth应用,然后白名单指定应用

gam update org "/" settings oauth_access block_all gam update org "/" settings oauth_access whitelist client_id:APP_CLIENT_ID_1
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

禁用外部Drive共享和文件传输

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
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
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:dmarc-reports@company.com; pct=100

预期配置:v=DMARC1; p=reject; rua=mailto:dmarc-reports@company.com; 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

---
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 # 受 compromise 的设备

---

6. AWS Account Security

6. AWS账户安全

bash
undefined
bash
undefined

Root account lockdown — verify MFA, remove access keys

根账户锁定——验证MFA状态,移除访问密钥

aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled' aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'
aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled' aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'

SSO permission set with least privilege

最小权限的SSO权限集

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"
undefined
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"
undefined

Service Control Policies

服务控制策略(SCP)

json
{
  "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": "*"}
  ]
}
bash
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}"
json
{
  "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": "*"}
  ]
}
bash
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

组织级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

---
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 App Review

7. OAuth应用审查

Identify High-Risk Grants

识别高风险授权

bash
undefined
bash
undefined

Google — find apps with dangerous scopes

Google — 查找具有危险权限范围的应用

gam all users show tokens | grep -E "(drive|gmail|admin)" > high_risk_oauth.txt
gam all users show tokens | grep -E "(drive|gmail|admin)" > high_risk_oauth.txt

GitHub — find apps with write access

GitHub — 查找具有写入权限的应用

gh api /orgs/{ORG}/installations --paginate
--jq '.installations[] | select(.permissions.contents == "write") | {app: .app_slug}'
undefined
gh api /orgs/{ORG}/installations --paginate
--jq '.installations[] | select(.permissions.contents == "write") | {app: .app_slug}'
undefined

Revoke Dangerous Grants

撤销危险授权

bash
gam user compromised@company.com delete token clientid APP_CLIENT_ID  # single app
gam user compromised@company.com 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"}'
bash
gam user compromised@company.com delete token clientid APP_CLIENT_ID  # 单个应用
gam user compromised@company.com delete tokens                        # 所有应用
gh api -X DELETE /orgs/{ORG}/installations/{INSTALLATION_ID}           # GitHub应用
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"}'

Scope Risk Classification

权限范围风险分级

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

CRITICAL(高危)—— 除非有正当理由否则立即撤销:
  Google: mail.google.com, admin.directory.user | GitHub: admin:org, repo | Slack: admin
HIGH(中危)—— 需仔细审查:
  Google: googleapis.com/auth/drive | GitHub: contents:write | Slack: channels:read
LOW(低危)—— 通常安全:
  Google: userinfo.email | GitHub: read:org | Slack: identity.basic

8. Admin Account Protection

8. 管理员账户保护

bash
undefined
bash
undefined

Dedicated admin account in Google Workspace

在Google Workspace中创建专用管理员账户

gam create user admin-jdoe@company.com firstname "John (Admin)" lastname "Doe"
password "$(openssl rand -base64 32)" org "/Admins" gam update user admin-jdoe@company.com admin on
gam create user admin-jdoe@company.com firstname "John (Admin)" lastname "Doe"
password "$(openssl rand -base64 32)" org "/Admins" gam update user admin-jdoe@company.com admin on

Require hardware security keys for the Admins OU

要求Admins组织单元使用硬件安全密钥

gam update org "/Admins" settings 2sv security_key_only
gam update org "/Admins" settings 2sv security_key_only

AWS MFA enforcement policy

AWS MFA强制策略

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
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

为SSO故障创建应急管理员账户

BREAK_GLASS_PW=$(openssl rand -base64 48) gam create user breakglass@company.com firstname "Break" lastname "Glass"
password "${BREAK_GLASS_PW}" org "/Admins" admin on
BREAK_GLASS_PW=$(openssl rand -base64 48) gam create user breakglass@company.com 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. Data Loss Prevention

9. 数据丢失防护(DLP)

bash
undefined
bash
undefined

Google Drive — block external sharing and restrict viewers

Google Drive — 阻止外部共享并限制查看者权限

gam update org "/" settings drive sharing_outside_domain off gam update org "/" settings drive disable_download_print_copy_for_viewers on
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

GitHub — 启用组织级密钥扫描和推送保护

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}'
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

Slack — 限制仅组织管理员可导出数据

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"}'
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 — 在账户级别阻止所有S3公共访问

aws s3control put-public-access-block --account-id "${AWS_ACCOUNT_ID}"
--public-access-block-configuration
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

---
aws s3control put-public-access-block --account-id "${AWS_ACCOUNT_ID}"
--public-access-block-configuration
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

---

10. Shadow IT Detection

10. 影子IT检测

DNS-Based Discovery

基于DNS的发现

bash
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
bash
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 Login Audit

Google Workspace登录审计

bash
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
bash
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

Proxy Log Analysis

代理日志分析

bash
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
bash
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

Automated Alerting

自动化告警

bash
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" security@company.com <<< "${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

bash
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" security@company.com <<< "${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

Quick Reference — Top 10 Priority Actions

快速参考——十大优先行动

#ActionScope
1Enforce MFA/2FA everywhereGoogle, GitHub, AWS, Slack
2Enable SSO with your IdPAll tools
3Audit and revoke OAuth grantsGoogle, GitHub
4Require Slack app approvalSlack
5Branch protection on mainGitHub
6Secret scanning + push protectionGitHub
7Block public S3 bucketsAWS
8Enable org-wide CloudTrailAWS
9Disable external Drive sharingGoogle
10Create break-glass admin accountsGoogle, AWS
#行动适用范围
1全面强制启用MFA/2FAGoogle、GitHub、AWS、Slack
2通过身份提供商启用SSO所有工具
3审计并撤销OAuth授权Google、GitHub
4启用Slack应用审批要求Slack
5配置主分支保护GitHub
6启用密钥扫描+推送保护GitHub
7阻止S3公共存储桶AWS
8启用组织级CloudTrailAWS
9禁用Drive外部共享Google
10创建应急管理员账户Google、AWS

Maintenance Cadence

维护周期

Weekly: Review OAuth grants, secret scanning alerts, Slack app queue. Monthly: AWS IAM report, rotate service keys, admin account review, shadow IT scan. Quarterly: Full SaaS inventory refresh, OAuth pruning, break-glass test, SCP updates.
每周: 审查OAuth授权、密钥扫描告警、Slack应用审批队列。 每月: AWS IAM报告、轮换服务密钥、管理员账户审查、影子IT扫描。 每季度: 全面更新SaaS资产清单、清理OAuth授权、测试应急账户、更新SCP策略。