google-agents-cli-scaffold
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
security-review-skill-for-terraform
审计 Terraform / IaC 代码安全(AWS 基础设施)。检测硬编码凭据、过宽 Security Group(0.0.0.0/0)、IAM 权限过大(Action/Resource *)、S3 公开访问、RDS 未加密/公开、State 文件泄露、ECS/EKS 容器特权、CloudTrail/VPC FlowLog 缺失、不安全 Provider/Module 引用等。当审计 Terraform 代码、IaC 安全评审、AWS 云基础设施配置检查、GitOps 安全审计时使用。支持 HCL(.tf)、Terraform JSON、tfvars、Terragrunt(HCL) 代码。
Full skill instructions
Terraform (HCL) 基础设施即代码安全审计,聚焦 AWS Provider。
审计范围:
.tf 文件(HCL 资源定义).tfvars / terraform.tfvars(变量值文件)backend.tf / provider.tf(后端和 Provider 配置)modules/(自定义和第三方模块)terragrunt.hcl(如使用 Terragrunt).terraform.lock.hcl(Provider 锁定文件)关键审计维度:
触发 skill 后,首先用 AskUserQuestion 询问用户审计模式:
问题: "选择审计模式" 选项:
git diff 中的 .tf/.tfvars 文件)如果用户 prompt 中已明确指定模式,跳过询问。
Step 0: 确定 diff 范围
git diff --name-only <base>...<target> -- '*.tf' '*.tfvars' 'terragrunt.hcl'
Step 0.1: 范围分析
核心原则:宁可漏过也不误报。所有发现必须基于实际代码。IaC 审计特点:配置即代码——缺失安全配置本身就是漏洞。
required_providers block → AWS(主要)/ Kubernetes / Helmbackend block → S3(推荐)/ Consul / Localresource 和 data 类型,构建攻击面module block 的 source 属性 → 本地/Registry/Gitvariable → locals → resource 属性的数据流根据下方"审计正则速查"逐条 Grep。IaC 正则扫描是核心检测手段——Terraform 安全问题大多是配置模式匹配。
Sink-driven(找危险配置):
*)、公开存储桶Control-driven(找缺失的安全控制):
IaC 数据流 = 变量传播:
variable "db_password" → local.config → resource.aws_db_instance.password
→ tfvars 文件中是否明文?
→ State 文件中是否存储?
追踪:
variable 定义是否标记 sensitive = trueuser_data 脚本)terraform_remote_state 读取是否暴露其他环境的敏感数据?攻击方:如果获得对此基础设施的只读/读写权限,能做什么? 防御方:是否有 WAF/SecurityGroup/NACL/IAM boundary 阻止?
0.0.0.0/0 在 egress 规则中通常是合理的(出站全放行)description 字段中包含密码样例字符串不是凭据泄露terraform.tfvars.example 中的占位值不是真实凭据data.aws_iam_policy_document 中 actions = ["s3:GetObject"] + resources = ["*"] 对只读 S3 可能是合理的count = 0 或 for_each = {} 的资源不会实际创建dynamic block 中的 content 可能有条件控制| 优先级 | 目标 | 原因 |
|---|---|---|
| P0 | 硬编码凭据/密钥 | 直接泄露即可攻陷 |
| P0 | 0.0.0.0/0 ingress + 敏感端口 | 互联网直接暴露 |
| P0 | IAM *:* 权限 | 等同管理员,极度危险 |
| P1 | S3 公开访问 | 数据泄露 |
| P1 | 数据库/存储未加密 | 合规 + 数据保护 |
| P1 | State 文件无加密/无远程后端 | State 含所有密钥 |
| P2 | 模块来源未锁版本 | 供应链攻击 |
| P2 | 日志/监控缺失 | 无法检测攻击 |
| P2 | 容器特权/root | 容器逃逸 |
硬编码凭据:
# 危险:明文密码
resource "aws_db_instance" "main" {
password = "MyS3cretP@ss!" # 硬编码
}
resource "aws_iam_access_key" "user" {
user = aws_iam_user.example.name
# access_key/secret_key 会存入 State
}
# 安全:引用 Secrets Manager
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db.secret_string
}
# 安全:标记 sensitive
variable "db_password" {
type = string
sensitive = true
}
State 文件中的密钥:
# 危险:本地 State(含所有资源属性,包括密码)
terraform {
backend "local" {} # State 文件存在本地磁盘
}
# 安全:远程 State + 加密
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "prod/terraform.tfstate"
encrypt = true
dynamodb_table = "tf-locks"
}
}
过宽 Security Group:
# 危险:全开入站
resource "aws_security_group_rule" "bad" {
type = "ingress"
from_port = 0
to_port = 65535
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
# 危险:SSH/RDP 对公网开放
resource "aws_security_group_rule" "ssh_open" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # SSH 对全互联网开放
}
# 安全:限制到 VPN/堡垒机 IP
resource "aws_security_group_rule" "ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"] # 仅内网
}
VPC Endpoint 缺失:
# 危险:S3 流量走公网(可被拦截)
# 无 aws_vpc_endpoint for s3
# 安全:VPC Endpoint 限制 S3 访问
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-southeast-1.s3"
route_table_ids = [aws_route_table.private.id]
policy = jsonencode({
Statement = [{
Effect = "Allow"
Principal = "*"
Action = "s3:*"
Resource = ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
}]
})
}
过宽 IAM 策略:
# 危险:管理员权限
resource "aws_iam_policy" "admin" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "*" # 全部操作
Resource = "*" # 全部资源
}]
})
}
# 危险:通配符 Action
resource "aws_iam_policy" "too_wide" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "s3:*" # S3 全部操作
Resource = "*"
}]
})
}
# 安全:最小权限
resource "aws_iam_policy" "minimal" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:ListBucket"]
Resource = [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
})
}
AssumeRole 信任过宽:
# 危险:任何 AWS 账户可 AssumeRole
resource "aws_iam_role" "bad" {
assume_role_policy = jsonencode({
Statement = [{
Effect = "Allow"
Principal = { AWS = "*" } # 任何人
Action = "sts:AssumeRole"
}]
})
}
存储未加密:
# 危险:S3 无服务端加密
resource "aws_s3_bucket" "data" {
bucket = "sensitive-data"
# 缺少 server_side_encryption_configuration
}
# 危险:RDS 未加密
resource "aws_db_instance" "main" {
storage_encrypted = false # 或缺失此属性
}
# 危险:EBS 未加密
resource "aws_ebs_volume" "data" {
encrypted = false
}
# 安全
resource "aws_s3_bucket_server_side_encryption_configuration" "enc" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
S3 公开:
# 危险:S3 公开读
resource "aws_s3_bucket_acl" "public" {
bucket = aws_s3_bucket.data.id
acl = "public-read"
}
# 危险:S3 公开访问未阻止
resource "aws_s3_bucket_public_access_block" "bad" {
bucket = aws_s3_bucket.data.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
# 安全
resource "aws_s3_bucket_public_access_block" "secure" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
数据库公开:
# 危险
resource "aws_db_instance" "public_db" {
publicly_accessible = true
}
# 危险:ElastiCache 无加密
resource "aws_elasticache_replication_group" "bad" {
at_rest_encryption_enabled = false
transit_encryption_enabled = false
}
# 危险:EKS API Server 公开
resource "aws_eks_cluster" "public" {
vpc_config {
endpoint_public_access = true
public_access_cidrs = ["0.0.0.0/0"]
}
}
Provider 版本未锁定:
# 危险:无版本约束
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
# 缺少 version 约束
}
}
}
# 安全
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
调试/开发模式:
# 危险:输出敏感值
output "db_password" {
value = aws_db_instance.main.password
# 缺少 sensitive = true
}
资源无备份/版本化:
# 危险:S3 无版本化(数据可被覆盖/删除)
resource "aws_s3_bucket_versioning" "none" {
bucket = aws_s3_bucket.data.id
versioning_configuration {
status = "Disabled"
}
}
# 危险:RDS 无备份
resource "aws_db_instance" "no_backup" {
backup_retention_period = 0
}
无删除保护:
# 危险:生产数据库可被 terraform destroy 直接删除
resource "aws_db_instance" "prod" {
deletion_protection = false # 或缺失
}
危险 Sink(安全敏感属性):
| 类别 | Resource.Attribute | 风险 |
|---|---|---|
| 凭据 | *.password, *.secret_key, *.access_key, *.token | 硬编码凭据 |
| 网络 | *.cidr_blocks, *.source_ranges, *.ip_range_filter | 过宽网络 |
| IAM | *.policy (JSON), *.actions, *.principal | 权限过大 |
| 加密 | *.encrypted, *.kms_key_id, *.sse_algorithm | 未加密 |
| 公开 | *.publicly_accessible, *.acl, *.public_access | 公开暴露 |
| 计算 | *.privileged, *.user_data, *.root_block_device | 容器/实例安全 |
| 日志 | *.logging, *.access_logs, *.trail | 监控缺失 |
Source(配置值来源):
variable 定义 → 检查是否 sensitive = trueterraform.tfvars / *.auto.tfvars → 检查是否含明文凭据data source → 检查是否从不可信源读取locals → 检查是否拼接生成不安全配置templatefile() / user_data → 检查内嵌脚本安全以下正则在 Step 2 必须逐条执行 Grep:
*.tf + *.tfvars 文件)| # | 类型 | 正则 | 说明 |
|---|---|---|---|
| T1 | 硬编码凭据 | (?:password|secret|token|api_key|access_key)\s*=\s*"[^"]{8,}" | 明文凭据赋值 |
| T2 | 硬编码凭据 | (?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16} | AWS Access Key ID |
| T3 | 硬编码凭据 | (?:BEGIN\s+(?:RSA|DSA|EC|OPENSSH)\s+PRIVATE\s+KEY) | 私钥文件内容 |
| T4 | 过宽网络 | (?:cidr_blocks|source_ranges|ip_range_filter)\s*=\s*\[?"?0\.0\.0\.0/0 | 全开入站 CIDR |
| T5 | 过宽网络 | (?:cidr_blocks|source_ranges)\s*=\s*\[?"::/0 | IPv6 全开 |
| T6 | 敏感端口 | (?:from_port|to_port)\s*=\s*(?:22|3389|3306|5432|6379|27017|9200) | SSH/RDP/DB 端口 |
| T7 | IAM 通配符 | "Action"\s*:\s*(?:"\*"|\["\*"\]) | IAM 全部操作 |
| T8 | IAM 通配符 | "Resource"\s*:\s*(?:"\*"|\["\*"\]) | IAM 全部资源 |
| T9 | IAM 通配符 | actions\s*=\s*\["\*"\] | data.aws_iam_policy_document 通配 |
| T10 | IAM Principal | "Principal"\s*:\s*(?:"\*"|\{"AWS"\s*:\s*"\*"\}) | 任何人可访问 |
| T11 | S3 公开 | acl\s*=\s*"(?:public-read|public-read-write|authenticated-read)" | S3 公开 ACL |
| T12 | S3 公开 | block_public_acls\s*=\s*false | 未阻止公开访问 |
| T13 | 未加密 | (?:storage_encrypted|encrypted)\s*=\s*false | 存储未加密 |
| T14 | 未加密 | (?:at_rest_encryption_enabled|encryption_at_rest)\s*=\s*false | 静态加密关闭 |
| T15 | 公开DB | publicly_accessible\s*=\s*true | 数据库公开 |
| T16 | 版本缺失 | source\s*=\s*"[^"]+"\s*$ + 同一 block 无 version | Provider/Module 无版本 |
| T17 | 特权容器 | privileged\s*=\s*true | 容器特权模式 |
| T18 | Root 容器 | user\s*=\s*"?(?:0|root)"? | 容器 root 用户 |
| T19 | 无删除保护 | deletion_protection\s*=\s*false | 无删除保护 |
| T20 | 敏感输出 | output\s+"[^"]*(?:password|secret|key|token)[^"]*" + 无 sensitive = true | 输出敏感值未标记 |
| T21 | 本地后端 | backend\s+"local" | 本地 State(不安全) |
| T22 | State 未加密 | encrypt\s*=\s*false | 远程 State 未加密 |
| T23 | 无备份 | backup_retention_period\s*=\s*0 | RDS 无备份 |
| T24 | 日志关闭 | (?:logging|access_logs?|enable_logging)\s*=\s*false | 日志/审计关闭 |
| T25 | TLS 版本 | (?:minimum_tls_version|tls_version)\s*=\s*"(?:TLS1_0|TLSv1|TLSv1\.0|1\.0)" | 过旧 TLS |
| T26 | Sensitive 缺失 | variable\s+"[^"]*(?:password|secret|token|key)[^"]*"\s*\{ + 无 sensitive\s*=\s*true | 敏感变量未标记 |
| T27 | User Data | user_data\s*=\s* | 检查 EC2 user_data 内容 |
| T28 | 模块来源 | source\s*=\s*"(?:git::|github\.com|bitbucket\.org) | Git 远程模块(检查版本锁定) |
| T29 | SSM 明文 | type\s*=\s*"String" (aws_ssm_parameter) | SSM Parameter 应使用 SecureString |
| T30 | GuardDuty | 检查 aws_guardduty_detector 是否存在 | 威胁检测未启用 |
| T31 | WAF 缺失 | 检查公网 ALB 是否关联 aws_wafv2_web_acl_association | 无 WAF 防护 |
| T32 | CloudFront HTTP | viewer_protocol_policy\s*=\s*"allow-all" | CloudFront 允许 HTTP |
| T33 | API GW 无认证 | authorization\s*=\s*"NONE" | API Gateway 无认证 |
| T34 | ECR 扫描 | 检查 aws_ecr_repository 是否有 image_scanning_configuration | 容器镜像无扫描 |
执行方式:对每条正则,Grep 搜索目标目录全部
.tf/.tfvars文件。匹配结果逐一分析。零匹配 = 该类型安全。
| 威胁 | 检查点 |
|---|---|
| State 文件泄露 | State 含所有资源属性(包括密码、密钥)。检查 backend 配置、State 文件权限 |
| Provider 认证 | Provider 凭据如何提供?硬编码/环境变量/AssumeRole? |
| Plan/Apply 权限 | CI/CD 中 terraform apply 的权限是否过大? |
| Module 供应链 | 第三方模块是否可信?版本是否锁定? |
| Drift 检测 | 手动变更是否会被覆盖或遗漏? |
| Import 安全 | terraform import 是否引入了不安全的既有资源? |
| 威胁 | 资源类型 | 检查属性 |
|---|---|---|
| S3 数据泄露 | aws_s3_bucket | acl, public_access_block, policy |
| RDS 暴露 | aws_db_instance | publicly_accessible, storage_encrypted |
| SG 过宽 | aws_security_group_rule | cidr_blocks + from_port |
| IAM 提权 | aws_iam_policy | Action: *, Resource: * |
| Lambda 权限 | aws_lambda_function | role, environment.variables |
| ECS 特权 | aws_ecs_task_definition | privileged, user |
| CloudTrail 缺失 | aws_cloudtrail | 资源是否存在 |
| 威胁 | 资源类型 | 检查属性 |
|---|---|---|
| Secrets 明文 | aws_ssm_parameter | type = "SecureString" + key_id |
| WAF 缺失 | aws_wafv2_web_acl | 是否关联到公网 ALB/API Gateway/CloudFront |
| CloudFront 不安全 | aws_cloudfront_distribution | viewer_protocol_policy, minimum_protocol_version |
| API Gateway 公开 | aws_api_gateway_rest_api | 认证方式、throttling、WAF 关联 |
| Route53 DNSSEC | aws_route53_zone | DNSSEC 签名是否启用 |
| SNS/SQS 未加密 | aws_sns_topic / aws_sqs_queue | kms_master_key_id |
| GuardDuty 未启用 | aws_guardduty_detector | 资源是否存在 |
| Security Hub 未启用 | aws_securityhub_account | 资源是否存在 |
| Config 未启用 | aws_config_configuration_recorder | 资源是否存在 |
| SCP 缺失 | aws_organizations_policy | Service Control Policy 限制危险操作 |
| 威胁 | 检查点 |
|---|---|
| 特权容器 | privileged = true, allow_privilege_escalation = true |
| HostPath 挂载 | host_path volume mount |
| 默认 SA | automount_service_account_token = true |
| 公开 API Server | endpoint_public_access = true + public_access_cidrs = ["0.0.0.0/0"] |
| 过宽 RBAC | cluster-admin binding |
Kill Switch 条件(命中任一 → 非漏洞):
type = "ingress" 时报告*.example, *.template, *.sample → 跳过# password = "old_value" → 非生效配置encrypted = var.enable_encryption(变量控制)→ 检查变量默认值data.aws_iam_policy_document 中只读操作 + * 资源可能合理 → 需结合上下文判断dev/, staging/, sandbox/ → 降低严重性但仍报告需要二次确认的模式:
cidr_blocks = var.allowed_cidr → 需检查变量默认值和实际 tfvarskms_key_id = "" 或缺失 → 某些资源默认使用 AWS managed key,需确认lifecycle { prevent_destroy = false } → 需确认是否是生产资源Source: variable 定义 / tfvars / 环境变量 / data source
Propagation: locals 计算 / module 参数传递 / templatefile()
Sink: resource 安全敏感属性(见上方 Sink 表)
追踪规则:
variable 含 password/secret/token/key → 标记为敏感数据流locals / resource / module 中的所有引用根据审计目标,必须先 Read 对应检查文件再开始审计:
| 代码路径模式 | 加载 checks/ |
|---|---|
**/sg*.tf, **/security*.tf, **/network*.tf, **/firewall*.tf | network-security.md |
**/iam*.tf, **/role*.tf, **/policy*.tf | iam-access-control.md |
**/s3*.tf, **/rds*.tf, **/storage*.tf, **/db*.tf | data-storage-security.md |
**/ecs*.tf, **/eks*.tf, **/k8s*.tf, **/lambda*.tf | compute-container-security.md |
backend.tf, provider.tf, versions.tf, modules/ | state-provider-module.md |
**/cloudtrail*.tf, **/logging*.tf, **/monitoring*.tf | logging-compliance.md |
| 审计目标 | 读取文件 |
|---|---|
| 网络安全 / SG / 防火墙 | checks/network-security.md |
| IAM / 权限 / 角色 | checks/iam-access-control.md |
| 数据存储 / S3 / RDS / 加密 | checks/data-storage-security.md |
| 容器 / ECS / EKS / K8s | checks/compute-container-security.md |
| State / Provider / Module | checks/state-provider-module.md |
| 日志 / 监控 / 合规 | checks/logging-compliance.md |
| 全量审计 | 按优先级依次读取所有 checks/ |
已知问题对照:审计完成后 Read known-issues/attack-patterns.md 对照攻击模式。
{
"scan_mode": "full | pr | recent_changes",
"diff_scope": {
"base": "main",
"target": "feature-branch",
"changed_files": ["modules/network/main.tf"],
"related_files": ["modules/network/variables.tf"]
},
"findings": [
{
"severity": "CRITICAL/HIGH/MEDIUM/LOW",
"type": "漏洞类型",
"location": "file:line",
"in_diff": true,
"resource": "aws_security_group_rule.ssh_open",
"description": "SSH 端口(22)对 0.0.0.0/0 开放",
"current_config": "cidr_blocks = [\"0.0.0.0/0\"]",
"expected_config": "cidr_blocks = [\"10.0.0.0/8\"]",
"attack_scenario": "攻击者可从互联网暴力破解 SSH",
"defense_analysis": "未发现其他网络层防护(WAF/NACL)",
"remediation": "限制 CIDR 到 VPN/堡垒机 IP 段",
"cwe": "CWE-284"
}
]
}
Project scaffolding, deployment configuration, and CI/CD setup for Google ADK agents.
Set up tracing, logging, and monitoring for deployed ADK agents across Cloud Trace, BigQuery, and third-party platforms.
Enterprise Azure infrastructure architect generating Bicep or Terraform from workload descriptions.
Plan and configure production-ready Azure Kubernetes Service clusters with Day-0 and Day-1 best practices.
Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
Web search, scraping, extraction, crawling, and monitoring via ScrapeGraph AI CLI.
Skill for working with Firebase Hosting (Classic). Use this when you want to deploy static web apps, Single Page Apps (SPAs), or simple microservices. Do NOT use for Firebase App Hosting.
Deploy and manage web apps with Firebase App Hosting. Use this skill when deploying Next.js/Angular apps with backends.
Deploy applications and websites to Vercel. Use when the user requests deployment actions like "deploy my app", "deploy and give me the link", "push this live", or "create a preview deployment".
Build SEO-optimized pages at scale using templates, data, and proven playbook patterns.
Design and build isolated, reusable Convex backend components with clear boundaries and app-facing wrappers.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Opus.ai: Revolutionize Your Web Experience
Build a no-code AI app in minutes.
An IDE for code migration from legacy to modern frameworks through coding agents.
Automate CGI animation in live-action scenes
Branded artistic QR-code concepts
Launch a website in seconds with AI.
Streamline Your Coding Experience with AI Code Helper
Convert any screenshot or design to clean code.