示例源码与下载#

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

下载实验包。包内包含全部实验文档、应用与策略模板,不包含真实凭据。解压后进入 gcp-iam-handson 目录,再按章节执行命令。

网页是主要阅读入口;下载包用于保存和运行代码。文档中的命令不会因浏览页面而自动执行。云端步骤尚未端到端验证。

app/.dockerignore#

下载此文件

.venv
__pycache__
*.pyc
*.env

app/Dockerfile#

下载此文件

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
RUN useradd --create-home appuser
USER appuser
CMD ["sh", "-c", "exec gunicorn --bind 0.0.0.0:${PORT:-8080} --workers 1 --threads 4 main:app"]

app/main.py#

下载此文件

"""IAM teaching application. Uses ADC; never returns secret contents."""
import csv
import io
import json
import os
import uuid
from decimal import Decimal
from flask import Flask, jsonify
from google.cloud import secretmanager, storage

app = Flask(__name__)

@app.post('/report')
def report():
    stage = 'read_input'
    request_id = uuid.uuid4().hex
    try:
        client = storage.Client()
        raw = client.bucket(os.environ['INPUT_BUCKET']).blob('input.csv').download_as_text()
        rows = list(csv.DictReader(io.StringIO(raw)))
        total = sum((Decimal(row['amount']) for row in rows), Decimal('0'))
        stage = 'read_secret'
        secretmanager.SecretManagerServiceClient().access_secret_version(
            request={'name': os.environ['SECRET_VERSION']})
        stage = 'write_report'
        name = f'reports/{request_id}.json'
        result = {'rows': len(rows), 'total': str(total), 'request_id': request_id}
        client.bucket(os.environ['OUTPUT_BUCKET']).blob(name).upload_from_string(
            json.dumps(result), content_type='application/json', if_generation_match=0)
        print(json.dumps({'request_id': request_id, 'stage': 'complete'}), flush=True)
        return jsonify({**result, 'object': name})
    except Exception as error:
        # Record the operation and error class; never log tokens or secret payloads.
        print(json.dumps({'request_id': request_id, 'stage': stage,
                          'error_type': type(error).__name__}), flush=True)
        return jsonify(request_id=request_id, stage=stage,
                       error_type=type(error).__name__), 500

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=int(os.environ.get('PORT', '8080')))

app/requirements.txt#

下载此文件

Flask>=3.0,<4
gunicorn>=23,<24
google-cloud-storage>=3,<4
google-cloud-secret-manager>=2,<3

templates/custom-role.yaml#

下载此文件

title: Lab Object Reader
description: Read a known object in the IAM lab
stage: ALPHA
includedPermissions:
- storage.objects.get

templates/deny-read.json#

下载此文件

{
  "displayName": "IAM lab deny runtime object reads",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principal://iam.googleapis.com/projects/-/serviceAccounts/REPLACE_RUNTIME_SA_EMAIL"
        ],
        "deniedPermissions": [
          "storage.googleapis.com/objects.get"
        ]
      }
    }
  ]
}

templates/lab.env.example#

下载此文件

# 仅供以后在独立实验环境中填写;不含任何真实凭据。
export ORG_ID='REPLACE_ORGANIZATION_ID'
export NONPROD_FOLDER_ID='REPLACE_NONPROD_FOLDER_ID'
export PROJECT_ID='REPLACE_UNIQUE_DEV_PROJECT_ID'
export GOOGLE_CLOUD_PROJECT="$PROJECT_ID"
export REGION='asia-east1'
export ADMIN_EMAIL='REPLACE_LAB_ADMIN_EMAIL'
export DEV_EMAIL='REPLACE_LAB_DEVELOPER_EMAIL'
export QA_EMAIL='REPLACE_LAB_QA_EMAIL'
export DEV_GROUP='REPLACE_DEVELOPERS_GROUP_EMAIL'
export QA_GROUP='REPLACE_QA_GROUP_EMAIL'
export INPUT_BUCKET="${PROJECT_ID}-raw"
export OUTPUT_BUCKET="${PROJECT_ID}-reports"
export APP_SA="report-app@${PROJECT_ID}.iam.gserviceaccount.com"
export DEPLOY_SA="report-deployer@${PROJECT_ID}.iam.gserviceaccount.com"
export SECRET_ID='report-api-key'
export SERVICE='report-api'

templates/org-policy-key.yaml#

下载此文件

# 示例:传统约束。先检查有效策略和 managed 约束,填写后才可用于实验。
name: projects/REPLACE_PROJECT_NUMBER/policies/iam.disableServiceAccountKeyCreation
spec:
  rules:
  - enforce: true

templates/实验记录.md#

下载此文件

# IAM 实验记录

- 实验章节与时间:
- 状态:未执行 / 推演 / 已验证 / 失败待排查 / 已回滚
- 执行者与实际请求身份:
- 目标资源和权限:
- 前提及变更前状态:
- 本次变更:
- 预期允许的操作及原因:
- 预期拒绝的操作及原因:
- 实际结果与传播等待时间:
- 日志或策略证据:
- 发现的额外授权路径:
- 最小修复及复测:
- 清理内容与恢复状态:

不记录访问令牌、真实 Secret、密钥或个人敏感资料。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭