[APIGateway.3] API ゲートウェイRESTAPIステージでは AWS X-Ray トレースを有効にする必要があります を CloudFormation Guard でチェックする
こんにちは!クラウド事業本部コンサルティング部のたかくに(@takakuni_)です。
みなさん CloudFormation テンプレートをデプロイする前に、 Security Hub の検知項目に引っかかっていないか、チェックしたいなぁと思ったことはありますでしょうか。
そういった時に、役に立つのが CloudFormation Guard や cfn-nag、Trivy、Snyk IaC などです。
ただし、どれも AWS Foundational Security Best Practices v1.0.0 (FSBP) 標準には完全に準拠しきれていないです。AWS FSBP ベースでシステム構築している方も多いのではないでしょうか。
そこで今回は、コントロールの1つである API ゲートウェイRESTAPIステージでは AWS X-Ray トレースを有効にする必要があります
を CloudFormation Guard で表現してみます。
コントロールについて
今回のコントロールは REST API のステージで、 AWS X-Ray のトレーシング機能を有効にしているかどうかをチェックします。設定することで特定の API のメソッドに対してのレスポンスタイムやエラー率などを計測できます。
普段のパフォーマンス改善目的で、トレーシングを利用する用途があれば有効にしておきましょう。とくにそのような目的がないのであれば、ただただコスト増につながるため、無理に有効にしなくて良いかと思います。
作成したコード
作成したコードは以下になります。
#################################################
# API Gateway.03
#################################################
# [APIGateway.3] API Gateway REST API stages should have AWS X-Ray tracing enabled
# Control URL: https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html#apigateway-3
#
# Category: Detect > Detection services
# Severity: Low
# Resource type: AWS::ApiGateway::Stage
# AWS Config rule: api-gw-xray-enabled
# Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/api-gw-xray-enabled.html
let api_gw_xray_enabled = Resources.*[ Type == 'AWS::ApiGateway::Stage'
Metadata.guard.SuppressedRules not exists or
Metadata.guard.SuppressedRules.* != "API_GW_XRAY_ENABLED"
]
# AWS::ApiGateway::Stage
rule api_gw_xray_enabled_check when %api_gw_xray_enabled !empty {
%api_gw_xray_enabled.Properties {
# TracingEnabled が存在するかチェック
TracingEnabled exists
<<
RuleID: APIGateway.3
Category: Detect > Detection services
Severity: Low
Resource type: AWS::ApiGateway::Stage
Description: API Gateway REST API stages should have AWS X-Ray tracing enabled
>>
# TracingEnabled が存在し、ブール値が true かどうかチェック
when TracingEnabled exists {
TracingEnabled == true
<<
RuleID: APIGateway.3
Category: Detect > Detection services
Severity: Medium
Resource type: AWS::ApiGateway::Stage
Description: API Gateway REST API stages should have AWS X-Ray tracing enabled
>>
}
}
}
X-Ray の設定について
X-Ray のトレーシング設定は AWS::ApiGateway::Stage
の TracingEnabled
で行います。
Type: AWS::ApiGateway::Stage
Properties:
AccessLogSetting:
AccessLogSetting
CacheClusterEnabled: Boolean
CacheClusterSize: String
CanarySetting:
CanarySetting
ClientCertificateId: String
DeploymentId: String
Description: String
DocumentationVersion: String
MethodSettings:
- MethodSetting
RestApiId: String
StageName: String
Tags:
- Tag
TracingEnabled: Boolean
Variables:
Key: Value
そのため、AWS::ApiGateway::Stage
の TracingEnabled
が存在するか、存在している場合、値が true であるかどうかがチェックロジックになります。(非常にシンプルですね。)
テストしてみる
いつものように、テストコードを用意してみました。
# api-gw-xray-enabled.yaml
---
# テストケース1: 空のテンプレート
- name: Empty template
input: {}
expectations:
rules:
api_gw_xray_enabled_check: SKIP
# テストケース2: 空のリソースセクション
- name: Empty resources
input:
Resources: {}
expectations:
rules:
api_gw_xray_enabled_check: SKIP
# テストケース3: X-Ray トレース有効
- name: Tracing enabled
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: true
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: PASS
# テストケース4: X-Ray トレース無効
- name: Tracing disabled
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: false
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: FAIL
# テストケース5: TracingEnabled プロパティ未設定
- name: Missing TracingEnabled property
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: FAIL
# テストケース6: ルール抑制設定
- name: Rule suppressed
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Metadata:
guard:
SuppressedRules:
- "API_GW_XRAY_ENABLED"
Properties:
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: SKIP
# テストケース7: 複数のステージ(混在)
- name: Multiple stages with mixed compliance
input:
Resources:
CompliantStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: true
RestApiId: !Ref MyRestApi1
StageName: prod
NonCompliantStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: false
RestApiId: !Ref MyRestApi2
StageName: dev
expectations:
rules:
api_gw_xray_enabled_check: FAIL
# テストケース8: 無効な TracingEnabled 値(文字列)
- name: Invalid TracingEnabled value (string)
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: "true"
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: FAIL
# テストケース9: 無効な TracingEnabled 値(数値)
- name: Invalid TracingEnabled value (number)
input:
Resources:
MyApiStage:
Type: AWS::ApiGateway::Stage
Properties:
TracingEnabled: 1
RestApiId: !Ref MyRestApi
StageName: prod
expectations:
rules:
api_gw_xray_enabled_check: FAIL
想定通り、テストが通過していますね。
takakuni@ api_gateway % cfn-guard test -r api-gw-xray-enabled.guard -t tests/api_gateway/api-gw-xray-enabled.yaml
Test Case #1
Name: Empty template
PASS Rules:
api_gw_xray_enabled_check: Expected = SKIP
Test Case #2
Name: Empty resources
PASS Rules:
api_gw_xray_enabled_check: Expected = SKIP
Test Case #3
Name: Tracing enabled
PASS Rules:
api_gw_xray_enabled_check: Expected = PASS
Test Case #4
Name: Tracing disabled
PASS Rules:
api_gw_xray_enabled_check: Expected = FAIL
Test Case #5
Name: Missing TracingEnabled property
PASS Rules:
api_gw_xray_enabled_check: Expected = FAIL
Test Case #6
Name: Rule suppressed
PASS Rules:
api_gw_xray_enabled_check: Expected = SKIP
Test Case #7
Name: Multiple stages with mixed compliance
PASS Rules:
api_gw_xray_enabled_check: Expected = FAIL
Test Case #8
Name: Invalid TracingEnabled value (string)
PASS Rules:
api_gw_xray_enabled_check: Expected = FAIL
Test Case #9
Name: Invalid TracingEnabled value (number)
PASS Rules:
api_gw_xray_enabled_check: Expected = FAIL
まとめ
以上、「[APIGateway.3] API ゲートウェイRESTAPIステージでは AWS X-Ray トレースを有効にする必要があります
を CloudFormation Guard でチェックする」でした。CloudFormation Guard を勉強している方の参考になれば幸いです。
クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!