目次

AWS IAM Roles Anywhere 完全ガイド v2.0

オンプレミス・マルチクラウド環境への IAM ロール拡張

AWS IAM Roles Anywhere は、オンプレミス・エッジ・他クラウド環境のワークロードに AWS IAM ロール由来の一時認証情報を提供する無料セキュリティサービス です。X.509 証明書をベースに Trust Anchor を確立し、長期アクセスキーなしで AWS リソースへのセキュアアクセスを実現します。本ドキュメントは、IAM Roles Anywhere の仕組み・コンポーネント・ユースケース・実装パターン・ベストプラクティス・2025-2026 最新動向を体系的に解説する完全ガイドです。

ドキュメントの目的

本ガイドは以下を対象としています:

  • ハイブリッドクラウド構築者向け: オンプレミスから AWS へのセキュアアクセス設計
  • DevOps / CI/CD エンジニア向け: GitHub Actions・Jenkins・GitLab CI での認証統一
  • セキュリティアーキテクト向け: PKI・証明書管理・Subject DN マッピングの実装
  • マルチクラウド管理者向け: Azure / GCP との共存環境での IAM ロール活用
  • コンプライアンス / 監査向け: CloudTrail 監査ログ・アクセス制御の透明性
  • 意思決定者向け: Roles Anywhere vs OIDC / Vault / Workload Identity Federation の比較検討

2025-2026 年の IAM Roles Anywhere エコシステム

  • Post-Quantum Digital Certificates対応(2026 新機能):量子耐性暗号による将来対応
  • Subject DN Condition 拡張:より細粒度な証明書属性ベースのアクセス制御
  • CRL(Certificate Revocation List)検証自動化:即座の証明書失効対応
  • CloudTrail 統合強化:証明書シリアルナンバー追跡による一意性確保
  • EKS Pod Identity との組み合わせ:セルフホスト Kubernetes への拡張
  • Cross-Account Roles Anywhere:Organizations での一元管理

目次

  1. 概要
  2. IAM Roles Anywhere が解決する課題
  3. 主な特徴
  4. アーキテクチャ
  5. コアコンポーネント
  6. 主要ユースケース(15+)
  7. Trust Model / 信頼の確立
  8. Subject DN マッピング / 細粒度制御
  9. Profile と Session Policy
  10. 設定・操作の具体例
  11. AWS CLI での操作
  12. SDK 統合
  13. Infrastructure as Code(CDK / Terraform)
  14. 類似サービス比較表
  15. ベストプラクティス
  16. トラブルシューティング
  17. セキュリティのポイント
  18. 2025-2026 最新動向
  19. 学習リソース・参考文献
  20. 実装例・チェックリスト
  21. まとめ

概要

初心者向けメモ: IAM Roles Anywhere は「AWS 外のサーバーやコンテナが X.509 証明書を提示して一時 AWS 認証情報を取得する仕組み」です。オンプレミスの Jenkins が GitHub 認証ではなく証明書認証で AWS ECR にアクセス、といった使用パターンです。

定義

AWS IAM Roles Anywhere は以下を実現します:

機能 説明
X.509 証明書ベース認証 長期アクセスキー不要、PKI 基盤を活用
一時認証情報発行 最大 12 時間の短命クレデンシャル、自動失効
IAM ロール統一 オンプレミスと AWS で同じ IAM ロール・ポリシーを使用
Trust Anchor 信頼する CA(Private CA or 外部 CA)の登録・管理
CloudTrail 監査 すべての認証・アクセスを追跡可能、証明書シリアルで一意化
完全無料 追加コストなし(CloudTrail / Private CA は別途課金)

IAM Roles Anywhere が解決する課題 {#解決する課題}

1. オンプレミス環境での長期アクセスキー廃止

課題:データセンターのバッチサーバー・CI/CD システムが AWS アクセス用の IAM アクセスキーを環境変数に保存→漏洩リスク・ローテーション管理が複雑

IAM Roles Anywhere の解決

  • バッチサーバー + X.509 証明書
  • → IAM Roles Anywhere で一時認証情報を取得
  • → 15 分後に自動失効
  • → 長期キー不要

2. CI/CD パイプラインの認証統一

課題:GitHub Actions は OIDC で IAM ロール引き受け可能だが、社内 Jenkins・社内 GitLab では OIDC プロバイダーがない

解決:Jenkins サーバーが Roles Anywhere 対応エージェント(aws-rolesanywhere-credential-helper)で証明書認証

3. マルチクラウド環境でのアクセス管理

課題:Azure / GCP / 社内クラウドのワークロードが AWS にアクセスするとき、クラウドごと異なる認証機構

解決:全クラウドに X.509 証明書配布し、IAM Roles Anywhere で統一

4. Kubernetes(セルフホスト)での IAM 統合

課題:EKS Pod Identity(旧 IRSA)は EKS 専用。セルフホスト K8s では Pod に IAM ロールを直接割り当てられない

解決:Pod に証明書マウント→Roles Anywhere で AWS リソースアクセス


主な特徴 {#特徴}

1. PKI(Public Key Infrastructure)ベース

既存の Active Directory CS / AWS Private CA / HashiCorp Vault などの CA をそのまま活用できます。

2. 証明書ライフサイクル管理との統合

  • 証明書の CRL(Certificate Revocation List)検証自動実施
  • 失効した証明書の即座な無効化
  • CloudTrail で一意性追跡(証明書シリアルナンバー記録)

3. Subject DN による細粒度アクセス制御

証明書の Subject DN(例:CN=batch-server-01,OU=On-Prem,O=MyCompany)を IAM ポリシーの Condition で使用し、特定サーバーのみ特定ロール引き受けなどが可能

4. Session Policy による権限制限

Profile で Session Policy を定義し、取得した一時認証情報の権限をさらに制限可能

5. 無料

Trust Anchor / Profile / 認証情報発行など、Roles Anywhere 自体の利用料金はなし(ただし CloudTrail / Private CA は課金対象)


アーキテクチャ {#アーキテクチャ}

graph TD
    A["オンプレミス / エッジ / 他クラウド"] -->|X.509 証明書を提示| B["IAM Roles Anywhere<br/>CreateSession API"]
    B -->|Trust Anchor で CA 証明書検証| C["CA 検証<br/>CRL チェック"]
    C -->|検証成功| D["IAM Roles Anywhere<br/>Subject DN 評価"]
    D -->|Condition に合致| E["AssumeRole<br/>STS API 呼び出し"]
    E -->|一時認証情報を発行| F["一時クレデンシャル<br/>AccessKey / SecretKey<br/>SessionToken"]
    F -->|15 分〜12 時間有効| G["AWS リソースへアクセス<br/>S3 / EC2 / RDS 等"]
    H["IAM Role<br/>Trust Policy"] -.->|aws:SourceArn<br/>Trust Anchor ARN| E
    I["IAM Policy<br/>& Session Policy"] -.->|権限制限| G
graph LR
    TA["Trust Anchor<br/>(CA 証明書登録)"]
    PR["Profile<br/>(Role & Session Policy)"]
    RO["IAM Role<br/>(AssumeRole Trust)"]
    
    TA -->|参照| PR
    PR -->|引き受け| RO
    RO -->|CloudTrail 記録| CL["CloudTrail Log<br/>(証明書シリアル含む)"]

コンポーネント間の関係

コンポーネント 役割
Trust Anchor 信頼する CA 証明書を登録 AWS Private CA ARN / 外部 CA 証明書
Profile どの IAM ロール・権限制限を指定 profile-arn:aws:rolesanywhere:...
IAM Role Trust Policy で Trust Anchor・Roles Anywhere を信頼 arn:aws:iam::123456789012:role/OnPremRole
Session Policy 一時認証情報の権限を制限 s3:GetObject のみなど

コアコンポーネント {#コアコンポーネント}

1. Trust Anchor(信頼の基点)

Trust Anchor は IAM Roles Anywhere が信頼する CA を表します。2 つのタイプがあります:

A. AWS Private CA

AWS が提供するマネージド CA を Trust Anchor として登録。

メリット:

  • AWS ネイティブで統合が深い
  • CRL の自動更新
  • AWS KMS による秘密鍵保護

デメリット:

  • 別途 Private CA の月額料金($1 あたり)
  • セットアップ時間が必要
{
  "TrustAnchorArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e-c8f3-4a92-a6dc-5f2cac0e8b1f",
  "Enabled": true,
  "Source": {
    "SourceType": "AWS_PCM",
    "SourceData": {
      "CertificateAuthorityArn": "arn:aws:acm-pca:ap-northeast-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
    }
  }
}

B. 外部 CA

オンプレミスの ADCS・OpenSSL・HashiCorp Vault などから発行された CA 証明書を登録。

メリット:

  • 既存 PKI 基盤をそのまま使用
  • 追加インフラ不要

デメリット:

  • CRL 管理は手動
  • 証明書更新・失効チェックを自分で運用
{
  "TrustAnchorArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/external-ca-anchor",
  "Enabled": true,
  "Source": {
    "SourceType": "CERTIFICATE",
    "SourceData": {
      "X509CertificateData": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAgI...\n-----END CERTIFICATE-----"
    }
  }
}

2. Profile(Role & Policy 定義)

Profile は「どの IAM ロールを引き受けるか」「どのような Session Policy で権限を制限するか」を定義します。

{
  "ProfileArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile",
  "ProfileName": "batch-profile",
  "Enabled": true,
  "RoleArns": [
    "arn:aws:iam::123456789012:role/OnPremBatchRole"
  ],
  "SessionPolicy": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "s3:GetObject",
          "s3:PutObject"
        ],
        "Resource": "arn:aws:s3:::my-bucket/*"
      }
    ]
  }
}

Key Points:

  • 1 つの Profile は複数の IAM ロールを参照可能
  • Session Policy により、ロール権限をさらに制限(権限の交差をとる)
  • MAU(Monthly Active Users)ではなく、認証回数で課金(無料)

3. Subject DN マッピング

証明書の Subject Distinguished Name を IAM ポリシー Condition で使用し、特定サーバーのみ特定ロール引き受けを制限します。

例:バッチサーバー 01 のみ S3 バケット A にアクセス

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/my-ca",
          "aws:x509SubjectAlt": "batch-server-01.internal"
        }
      }
    }
  ]
}

主要ユースケース(15+) {#ユースケース}

1. オンプレミスバッチサーバー → AWS S3 への定期アップロード

Batch Server(Linux/Windows)
    ├─ X.509 証明書配置(/etc/pki/rolesanywhere/cert.pem)
    ├─ Roles Anywhere credential helper インストール
    └─ cron/Task Scheduler で定期実行
        → CSV ファイルを AWS S3 にアップロード

メリット:

  • IAM アクセスキーを環境変数に保存不要
  • 証明書失効で即座にアクセス停止
  • CloudTrail で監査ログ記録

2. GitHub Actions / GitLab CI での Docker イメージ push

name: Build and Push Docker Image
on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Assume IAM Role via Roles Anywhere
        run: |
          aws-rolesanywhere-credential-helper \
            --trust-anchor-arn ${{ env.TRUST_ANCHOR_ARN }} \
            --profile-arn ${{ env.PROFILE_ARN }} \
            --cert-path /run/secrets/cert.pem \
            --key-path /run/secrets/key.pem
      - name: Push to ECR
        run: |
          aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
          docker push $ECR_REGISTRY/my-app:latest

3. セルフホスト Kubernetes Pod → AWS RDS 接続

apiVersion: v1
kind: Pod
metadata:
  name: db-access-pod
spec:
  serviceAccountName: rds-access
  containers:
  - name: app
    image: myapp:latest
    volumeMounts:
    - name: cert
      mountPath: /var/run/rolesanywhere
      readOnly: true
    env:
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::123456789012:role/RDSAccessRole
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/rolesanywhere/token
  volumes:
  - name: cert
    secret:
      secretName: rolesanywhere-cert

4. Jenkins パイプライン → AWS Lambda デプロイ

pipeline {
    agent any
    stages {
        stage('Deploy to Lambda') {
            steps {
                withEnv([
                    'ROLESANYWHERE_TRUST_ANCHOR=arn:aws:rolesanywhere:...',
                    'ROLESANYWHERE_PROFILE=arn:aws:rolesanywhere:...'
                ]) {
                    sh '''
                        eval $(aws-rolesanywhere-credential-helper --trust-anchor-arn $ROLESANYWHERE_TRUST_ANCHOR --profile-arn $ROLESANYWHERE_PROFILE)
                        aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip
                    '''
                }
            }
        }
    }
}

5. マルチクラウド環境:Azure VM → AWS S3

#!/bin/bash

# Azure VM に発行された X.509 証明書でロール引き受け
CERT_PATH="/etc/azure-certs/cert.pem"
KEY_PATH="/etc/azure-certs/key.pem"

# IAM Roles Anywhere で AWS 認証情報を取得
CREDENTIALS=$(aws-rolesanywhere-credential-helper \
  --trust-anchor-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/multi-cloud \
  --profile-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/azure-to-aws \
  --cert-path $CERT_PATH \
  --key-path $KEY_PATH)

# AWS S3 にデータ転送
export AWS_ACCESS_KEY_ID=$(echo $CREDENTIALS | jq -r .accessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $CREDENTIALS | jq -r .secretAccessKey)
export AWS_SESSION_TOKEN=$(echo $CREDENTIALS | jq -r .sessionToken)

aws s3 cp /data/important-file.tar.gz s3://aws-bucket/azure-exports/

6. オンプレミス Ansible Tower → AWS EC2 インベントリ更新

- name: Update AWS EC2 instances from Ansible Tower
  hosts: localhost
  vars:
    rolesanywhere_trust_anchor: "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/ansible-ca"
    rolesanywhere_profile: "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/ansible-profile"
  tasks:
    - name: Get temporary credentials from Roles Anywhere
      shell: |
        aws-rolesanywhere-credential-helper \
          --trust-anchor-arn {{ rolesanywhere_trust_anchor }} \
          --profile-arn {{ rolesanywhere_profile }} \
          --cert-path /etc/ansible/certs/cert.pem \
          --key-path /etc/ansible/certs/key.pem
      register: rolesanywhere_creds

    - name: Configure AWS credentials
      set_fact:
        aws_access_key: "{{ (rolesanywhere_creds.stdout | from_json).accessKeyId }}"
        aws_secret_key: "{{ (rolesanywhere_creds.stdout | from_json).secretAccessKey }}"
        aws_session_token: "{{ (rolesanywhere_creds.stdout | from_json).sessionToken }}"

    - name: Update EC2 instances
      ec2:
        instance_ids: "{{ instance_ids }}"
        aws_access_key: "{{ aws_access_key }}"
        aws_secret_access_key: "{{ aws_secret_key }}"
        security_token: "{{ aws_session_token }}"
        state: running

7. 工場の IoT デバイス → AWS IoT Core 接続

# IoT デバイスが X.509 証明書で AWS にテレメトリを送信
import requests
import json
import boto3

# Roles Anywhere で一時認証情報を取得
response = requests.post(
    'https://rolesanywhere.ap-northeast-1.amazonaws.com/CreateSession',
    json={
        'DurationSeconds': 900,
        'CertificateId': 'device-001-cert-serial',
        'TrustAnchorArn': 'arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/factory-devices',
        'ProfileArn': 'arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/iot-profile'
    },
    cert=('/etc/device-certs/cert.pem', '/etc/device-certs/key.pem')
)

credentials = response.json()

# AWS IoT に MQTT publish
iot_client = boto3.client('iot-data',
    region_name='ap-northeast-1',
    aws_access_key_id=credentials['credentials']['accessKeyId'],
    aws_secret_access_key=credentials['credentials']['secretAccessKey'],
    aws_session_token=credentials['credentials']['sessionToken']
)

iot_client.publish(
    topic='factory/sensor/temperature',
    qos=1,
    payload=json.dumps({'temp': 25.3, 'device_id': 'sensor-001'})
)

8. オンプレミス Oracle DB → AWS S3 バックアップ

#!/bin/bash

# Oracle DB バックアップを AWS S3 にアップロード

# 1. Roles Anywhere で認証情報取得
CREDS=$(aws-rolesanywhere-credential-helper \
  --trust-anchor-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/db-backup \
  --profile-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/db-backup \
  --cert-path /var/rolesanywhere/db-backup-cert.pem \
  --key-path /var/rolesanywhere/db-backup-key.pem)

export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .accessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .secretAccessKey)
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .sessionToken)

# 2. Oracle バックアップを実行
expdp userid=sys/password DUMPFILE=db_backup_%U.dmp PARALLEL=4

# 3. S3 にアップロード
aws s3 sync . s3://oracle-backups/$(date +%Y%m%d)/ --include "*.dmp"

# 4. ローカルバックアップ削除
rm -f db_backup_*.dmp

9. 社内 Vault サーバー → AWS Secrets Manager 同期

# Vault に保存されたシークレットを AWS Secrets Manager に同期

import hvac
import boto3

# Roles Anywhere で AWS 認証
sm_client = boto3.client('secretsmanager',
    region_name='ap-northeast-1',
    aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
    aws_session_token=os.environ['AWS_SESSION_TOKEN']
)

# Vault から シークレット取得
vault_client = hvac.Client(url='https://vault.internal:8200')
vault_client.auth.cert(cert_path='/etc/vault-certs/cert.pem', key_path='/etc/vault-certs/key.pem')

for secret_name in ['db/password', 'api/key', 'ssh/private']:
    secret_data = vault_client.secrets.kv.v2.read_secret_version(secret_name)['data']['data']
    
    # AWS Secrets Manager に保存
    sm_client.create_secret(
        Name=secret_name.replace('/', '-'),
        SecretString=json.dumps(secret_data)
    )

10. GitOps フロー:ArgoCD → AWS ECS ロールアウト

apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: argocd-rolesanywhere
spec:
  server:
    autoscale:
      enabled: true
  controller:
    serviceAccountName: argo-rolesanywhere
  dex:
    enabled: false
  rbac:
    policy: |
      g, argocd-admins, role:admin
      g, argocd-developers, role:developer
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: argo-rolesanywhere
---
apiVersion: v1
kind: Secret
metadata:
  name: rolesanywhere-creds
type: Opaque
stringData:
  trust-anchor-arn: arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/gitops
  profile-arn: arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/gitops
  cert.pem: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
  key.pem: |
    -----BEGIN PRIVATE KEY-----
    ...
    -----END PRIVATE KEY-----

11. DaaS(Desktop as a Service)VM → AWS リソースアクセス

# Windows DaaS VM から AWS リソースへのセキュアアクセス

# PowerShell スクリプト
$trustAnchorArn = "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/daas"
$profileArn = "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/daas-profile"
$certPath = "C:\ProgramData\RolesAnywhere\cert.pem"
$keyPath = "C:\ProgramData\RolesAnywhere\key.pem"

# Roles Anywhere Credential Helper を実行
$credentialsJson = & "C:\Program Files\AWS\RolesAnywhere\aws-rolesanywhere-credential-helper.exe" `
  --trust-anchor-arn $trustAnchorArn `
  --profile-arn $profileArn `
  --cert-path $certPath `
  --key-path $keyPath

$credentials = $credentialsJson | ConvertFrom-Json

# AWS CLI コンテキストで利用
$env:AWS_ACCESS_KEY_ID = $credentials.accessKeyId
$env:AWS_SECRET_ACCESS_KEY = $credentials.secretAccessKey
$env:AWS_SESSION_TOKEN = $credentials.sessionToken

# S3 からファイル取得
aws s3 cp s3://daas-resources/app-config.zip C:\temp\

12. コンテナレジストリ認証:Docker Image Pull

FROM ubuntu:22.04

# Roles Anywhere credential helper インストール
RUN apt-get update && apt-get install -y \
    aws-rolesanywhere-credential-helper \
    && rm -rf /var/lib/apt/lists/*

# 証明書をコンテナに組み込み(本番は Secret 管理)
COPY --chown=root:root cert.pem key.pem /etc/pki/rolesanywhere/

# アプリケーション
COPY app.sh /usr/local/bin/

ENTRYPOINT ["/usr/local/bin/app.sh"]
#!/bin/bash
# app.sh

# Roles Anywhere で認証
eval $(aws-rolesanywhere-credential-helper \
  --trust-anchor-arn $TRUST_ANCHOR_ARN \
  --profile-arn $PROFILE_ARN \
  --cert-path /etc/pki/rolesanywhere/cert.pem \
  --key-path /etc/pki/rolesanywhere/key.pem)

# ECR から イメージ pull
aws ecr get-login-password --region ap-northeast-1 | \
  docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

docker pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest
docker run --rm my-app:latest /app/service

13. Terraform State を S3 に保存(オンプレミス Terraform)

# backend.tf
terraform {
  backend "s3" {
    bucket         = "terraform-state-bucket"
    key            = "on-prem/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}
#!/bin/bash
# terraform-init.sh

# Roles Anywhere で AWS 認証
eval $(aws-rolesanywhere-credential-helper \
  --trust-anchor-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/terraform \
  --profile-arn arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/terraform \
  --cert-path /etc/rolesanywhere/terraform-cert.pem \
  --key-path /etc/rolesanywhere/terraform-key.pem)

# Terraform init
terraform init

# 以降の apply, destroy も自動的に Roles Anywhere 認証を使用
terraform plan
terraform apply

14. Lambda@Edge で CloudFront → オンプレミス Origin の認証

# Lambda@Edge で Viewer Request 時に認証情報を追加(オンプレミス Origin 向け)
import json
import requests
import os

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    
    # CloudFront viewer からのリクエスト
    viewer_request_header = request['headers'].get('x-viewer-token', [{}])[0].get('value')
    
    # バックエンド(オンプレミス)への認証
    # Roles Anywhere で一時認証情報を取得(ローカル実行の場合)
    try:
        # これは Lambda が ECS/Lambda ロール を持つ場合の例
        # ただしオンプレミス認証の場合は事前に credentials を設定
        auth_header = f"Bearer {os.environ.get('ORIGIN_AUTH_TOKEN')}"
    except:
        auth_header = "Bearer default-token"
    
    # Origin へのリクエストに認証ヘッダを追加
    request['headers']['authorization'] = [{'key': 'Authorization', 'value': auth_header}]
    
    return request

15. 監視・アラート:CloudWatch Logs Insights で失効証明書を検出

-- CloudTrail ログから失敗した Roles Anywhere 認証を検出
fields @timestamp, userIdentity.principalId, sourceIPAddress, errorMessage
| filter eventName = "CreateSession" and errorCode in ["UnauthorizedOperation", "InvalidCertificate"]
| stats count() as failed_auth_count by sourceIPAddress, errorMessage
| filter failed_auth_count > 5
| sort failed_auth_count desc

Trust Model / 信頼の確立 {#trustmodel}

Principal の信頼チェーン

X.509 証明書(エンドポイント)
    ↓ 検証
Trust Anchor(CA 証明書登録)
    ↓ Profile が参照
IAM Role(Trust Policy で Roles Anywhere を許可)
    ↓ AssumeRole
STS 認証情報(AccessKey / SecretKey / SessionToken)
    ↓ 一時認証(最大 12 時間)
AWS リソース(S3 / EC2 / RDS 等)

Role Trust Policy の設定例

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": [
            "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/my-ca",
            "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:x509SubjectAltName": "batch-server-01.internal"
        }
      }
    }
  ]
}

Subject DN マッピング / 細粒度制御 {#subjectdn}

証明書の Subject DN 構造

  • Subject: CN=batch-server-01,OU=Production,OU=On-Prem,O=MyCompany,C=JP
要素 説明 Condition Key
CN(Common Name) 証明書の主体(サーバー名) aws:x509SubjectAltName
OU(Organizational Unit) 部門・チーム 直接 Condition 対応なし(Policy で後処理)
O(Organization) 組織 直接 Condition 対応なし
C(Country) 国コード 直接 Condition 対応なし

サーバー単位でのアクセス制限例

シナリオ:本番バッチサーバー 01 のみ、本番 S3 バケットへのアクセスを許可

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowBatchServer01Only",
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/prod-batch-profile",
          "aws:x509SubjectAlt": "batch-server-01.internal"
        }
      }
    }
  ]
}

Profile と Session Policy {#sessionpolicy}

Session Policy とは

Profile 内で定義される IAM ポリシーで、一時認証情報の権限を「ロール権限」×「Session Policy」に制限します(権限の交差)。

例:S3 のみアクセス、特定バケット + 特定プレフィックス

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-prod-bucket/batch-imports/*"
    },
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::my-prod-bucket",
      "Condition": {
        "StringLike": {
          "s3:prefix": "batch-imports/*"
        }
      }
    }
  ]
}

設定・操作の具体例 {#設定操作}

CLI / SDK / IaC での実装例を後セクションで詳述


AWS CLI での操作 {#awscli}

1. Trust Anchor 作成(AWS Private CA)

aws rolesanywhere create-trust-anchor \
  --name "private-ca-anchor" \
  --enabled \
  --source \
    SourceType=AWS_PCM,SourceData='{
      "CertificateAuthorityArn":"arn:aws:acm-pca:ap-northeast-1:123456789012:certificate-authority/12345678-1234"
    }' \
  --region ap-northeast-1

出力:

{
  "trustAnchor": {
    "trustAnchorArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e-c8f3-4a92",
    "trustAnchorName": "private-ca-anchor",
    "enabled": true,
    "createdAt": "2026-04-26T10:00:00Z"
  }
}

2. Trust Anchor 作成(外部 CA 証明書)

# 外部 CA 証明書を PEM 形式で保存しておく
cat > external-ca.pem << 'EOF'
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIUXwZ1P...
...
-----END CERTIFICATE-----
EOF

aws rolesanywhere create-trust-anchor \
  --name "external-ca-anchor" \
  --enabled \
  --source \
    SourceType=CERTIFICATE,SourceData='{
      "X509CertificateData":"'"$(cat external-ca.pem)"'"
    }' \
  --region ap-northeast-1

3. Profile 作成

# Session Policy を JSON 形式で定義
cat > session-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::batch-bucket/*"
    }
  ]
}
EOF

aws rolesanywhere create-profile \
  --name "batch-profile" \
  --role-arns "arn:aws:iam::123456789012:role/BatchRole" \
  --session-policy file://session-policy.json \
  --enabled \
  --region ap-northeast-1

出力:

{
  "profile": {
    "profileArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile",
    "profileName": "batch-profile",
    "enabled": true,
    "roleArns": ["arn:aws:iam::123456789012:role/BatchRole"],
    "createdAt": "2026-04-26T10:00:00Z"
  }
}

4. IAM Role 作成(Trust Policy 設定)

# Trust Policy JSON
cat > trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": [
            "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e-c8f3",
            "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile"
          ]
        }
      }
    }
  ]
}
EOF

# Role 作成
aws iam create-role \
  --role-name BatchRole \
  --assume-role-policy-document file://trust-policy.json

# Permission Policy 作成
cat > permission-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:*"],
      "Resource": "arn:aws:s3:::batch-bucket/*"
    }
  ]
}
EOF

aws iam put-role-policy \
  --role-name BatchRole \
  --policy-name BatchPolicy \
  --policy-document file://permission-policy.json

5. CreateSession:認証情報取得

# オンプレミスサーバーで実行

TRUST_ANCHOR_ARN="arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e-c8f3"
PROFILE_ARN="arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile"
CERT_PATH="/etc/pki/rolesanywhere/cert.pem"
KEY_PATH="/etc/pki/rolesanywhere/key.pem"
DURATION=3600  # 1 時間

aws rolesanywhere create-session \
  --duration-seconds $DURATION \
  --trust-anchor-arn $TRUST_ANCHOR_ARN \
  --profile-arn $PROFILE_ARN \
  --cert-path $CERT_PATH \
  --key-path $KEY_PATH \
  --region ap-northeast-1

出力:

{
  "credentials": {
    "accessKeyId": "ASIAIN...",
    "secretAccessKey": "aBcDeFgHiJkLmNoPqRsTuVwXyZ...",
    "sessionToken": "IQoJb3JpZ2lu...",
    "expiration": "2026-04-26T11:00:00Z"
  }
}

6. 認証情報を環境変数に設定

# JSON パースして環境変数に設定
RESPONSE=$(aws rolesanywhere create-session \
  --trust-anchor-arn $TRUST_ANCHOR_ARN \
  --profile-arn $PROFILE_ARN \
  --cert-path $CERT_PATH \
  --key-path $KEY_PATH \
  --region ap-northeast-1)

export AWS_ACCESS_KEY_ID=$(echo $RESPONSE | jq -r '.credentials.accessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $RESPONSE | jq -r '.credentials.secretAccessKey')
export AWS_SESSION_TOKEN=$(echo $RESPONSE | jq -r '.credentials.sessionToken')

# 以降の AWS CLI コマンドは自動的に Roles Anywhere 認証を使用
aws s3 ls s3://batch-bucket/

7. Trust Anchor の一覧表示

aws rolesanywhere list-trust-anchors --region ap-northeast-1

# 出力
{
  "trustAnchors": [
    {
      "trustAnchorArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e",
      "trustAnchorName": "private-ca-anchor",
      "enabled": true,
      "createdAt": "2026-04-26T10:00:00Z"
    }
  ]
}

8. Profile の詳細表示

PROFILE_ARN="arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile"

aws rolesanywhere get-profile \
  --profile-arn $PROFILE_ARN \
  --region ap-northeast-1

# 出力
{
  "profile": {
    "profileArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile",
    "profileName": "batch-profile",
    "enabled": true,
    "roleArns": ["arn:aws:iam::123456789012:role/BatchRole"],
    "sessionPolicy": {...},
    "createdAt": "2026-04-26T10:00:00Z"
  }
}

9. 属性マッピングの設定(Subject DN)

# Profile に属性マッピングを追加(詳細設定)
aws rolesanywhere update-profile \
  --profile-arn "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/batch-profile" \
  --role-arns "arn:aws:iam::123456789012:role/BatchRole" \
  --attribute-mappings \
    IssuerName="CN=MyCA,O=MyCompany" \
    SerialNumber=".*" \
  --region ap-northeast-1

10. Certificate Revocation List(CRL)設定

# Trust Anchor に CRL エンドポイントを設定
aws rolesanywhere update-trust-anchor \
  --trust-anchor-arn "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e" \
  --source \
    SourceType=CERTIFICATE,SourceData='{
      "X509CertificateData":"...",
      "CrlUrl":"https://ca.internal.com/crl.pem"
    }' \
  --region ap-northeast-1

SDK 統合 {#sdk}

Python(boto3)

import boto3
import json
from pathlib import Path

class RolesAnywhereClient:
    def __init__(self, region='ap-northeast-1'):
        self.client = boto3.client('rolesanywhere', region_name=region)
        self.sts = boto3.client('sts', region_name=region)
    
    def create_session(self, trust_anchor_arn, profile_arn, cert_path, key_path, duration=3600):
        """Roles Anywhere で認証情報を取得"""
        # aws-rolesanywhere-credential-helper を subprocess で実行
        import subprocess
        
        result = subprocess.run([
            'aws-rolesanywhere-credential-helper',
            '--trust-anchor-arn', trust_anchor_arn,
            '--profile-arn', profile_arn,
            '--cert-path', cert_path,
            '--key-path', key_path,
            '--duration-seconds', str(duration)
        ], capture_output=True, text=True)
        
        return json.loads(result.stdout)
    
    def access_s3_with_rolesanywhere(self, credentials, bucket, key):
        """Roles Anywhere で取得した認証情報を使用して S3 にアクセス"""
        s3 = boto3.client(
            's3',
            aws_access_key_id=credentials['accessKeyId'],
            aws_secret_access_key=credentials['secretAccessKey'],
            aws_session_token=credentials['sessionToken']
        )
        
        return s3.get_object(Bucket=bucket, Key=key)

# 使用例
client = RolesAnywhereClient()
creds = client.create_session(
    trust_anchor_arn='arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/...',
    profile_arn='arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/...',
    cert_path='/etc/pki/rolesanywhere/cert.pem',
    key_path='/etc/pki/rolesanywhere/key.pem'
)

response = client.access_s3_with_rolesanywhere(creds, 'my-bucket', 'my-key.txt')
print(response['Body'].read().decode())

Java

import software.amazon.awssdk.services.rolesanywhere.RolesAnywhereClient;
import software.amazon.awssdk.services.rolesanywhere.model.*;
import software.amazon.awssdk.auth.credentials.*;

public class RolesAnywhereExample {
    
    public static void main(String[] args) {
        String trustAnchorArn = "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/...";
        String profileArn = "arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/...";
        String certPath = "/etc/pki/rolesanywhere/cert.pem";
        String keyPath = "/etc/pki/rolesanywhere/key.pem";
        
        try (RolesAnywhereClient client = RolesAnywhereClient.builder()
                .region(Region.AP_NORTHEAST_1)
                .build()) {
            
            CreateSessionRequest request = CreateSessionRequest.builder()
                    .trustAnchorArn(trustAnchorArn)
                    .profileArn(profileArn)
                    .durationSeconds(3600)
                    .build();
            
            CreateSessionResponse response = client.createSession(request);
            
            System.out.println("AccessKeyId: " + response.credentials().accessKeyId());
            System.out.println("Expiration: " + response.credentials().expiration());
        }
    }
}

Node.js

const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');

const rolesAnywhere = new AWS.RolesAnywhere({
    region: 'ap-northeast-1'
});

async function createSessionWithRolesAnywhere() {
    const params = {
        trustAnchorArn: 'arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/...',
        profileArn: 'arn:aws:rolesanywhere:ap-northeast-1:123456789012:profile/...',
        durationSeconds: 3600,
        certificatePath: '/etc/pki/rolesanywhere/cert.pem',
        keyPath: '/etc/pki/rolesanywhere/key.pem'
    };
    
    try {
        const response = await rolesAnywhere.createSession(params).promise();
        console.log('Credentials:', {
            accessKeyId: response.credentials.accessKeyId,
            expiration: response.credentials.expiration
        });
        
        // 取得した認証情報で S3 にアクセス
        const s3 = new AWS.S3({
            accessKeyId: response.credentials.accessKeyId,
            secretAccessKey: response.credentials.secretAccessKey,
            sessionToken: response.credentials.sessionToken
        });
        
        const objectParams = {
            Bucket: 'my-bucket',
            Key: 'my-file.txt'
        };
        
        const data = await s3.getObject(objectParams).promise();
        console.log(data.Body.toString());
    } catch (error) {
        console.error('Error:', error);
    }
}

createSessionWithRolesAnywhere();

Infrastructure as Code(CDK / Terraform) {#iac}

AWS CDK(Python)

from aws_cdk import (
    aws_rolesanywhere as rolesanywhere,
    aws_iam as iam,
    aws_acm_pca as acm_pca,
    core
)

class RolesAnywhereStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)
        
        # Private CA を作成(既存の場合はスキップ)
        # pca = acm_pca.CertificateAuthority(...)
        
        # IAM Role を作成
        batch_role = iam.Role(
            self, "BatchRole",
            assumed_by=iam.ServicePrincipal("rolesanywhere.amazonaws.com"),
            description="Role for on-premises batch servers"
        )
        
        # S3 アクセス権限を付与
        batch_role.add_to_policy(
            iam.PolicyStatement(
                effect=iam.Effect.ALLOW,
                actions=["s3:GetObject", "s3:PutObject"],
                resources=["arn:aws:s3:::batch-bucket/*"]
            )
        )
        
        # Trust Anchor を作成(AWS Private CA)
        # ca_arn = "arn:aws:acm-pca:..."  # 既存 CA
        # trust_anchor = rolesanywhere.TrustAnchor(
        #     self, "TrustAnchor",
        #     source=rolesanywhere.TrustAnchorSource.pca(ca_arn),
        #     enabled=True
        # )
        
        # Profile を作成
        session_policy = iam.PolicyDocument(
            statements=[
                iam.PolicyStatement(
                    effect=iam.Effect.ALLOW,
                    actions=["s3:GetObject", "s3:PutObject"],
                    resources=["arn:aws:s3:::batch-bucket/*"]
                )
            ]
        )
        
        # profile = rolesanywhere.Profile(
        #     self, "BatchProfile",
        #     role_arns=[batch_role.role_arn],
        #     session_policy=session_policy,
        #     enabled=True
        # )
        
        # Output
        core.CfnOutput(
            self, "BatchRoleArn",
            value=batch_role.role_arn,
            description="IAM Role ARN for batch servers"
        )

app = core.App()
RolesAnywhereStack(app, "RolesAnywhereStack")
app.synth()

Terraform

# variables.tf
variable "certificate_arn" {
  description = "AWS Private CA certificate ARN"
  type        = string
}

variable "environment" {
  default = "production"
}

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

# Trust Anchor(AWS Private CA)
resource "aws_rolesanywhere_trust_anchor" "batch_ca" {
  name    = "${var.environment}-batch-ca"
  enabled = true

  source {
    source_type = "AWS_PCM"
    source_data {
      acm_pca_arn = var.certificate_arn
    }
  }

  tags = {
    Environment = var.environment
  }
}

# IAM Role
resource "aws_iam_role" "batch_role" {
  name = "${var.environment}-batch-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "rolesanywhere.amazonaws.com"
        }
        Action = "sts:AssumeRole"
        Condition = {
          StringEquals = {
            "aws:SourceArn" = aws_rolesanywhere_trust_anchor.batch_ca.arn
          }
        }
      }
    ]
  })

  tags = {
    Environment = var.environment
  }
}

# IAM Policy
resource "aws_iam_role_policy" "batch_policy" {
  name = "${var.environment}-batch-policy"
  role = aws_iam_role.batch_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["s3:GetObject", "s3:PutObject"]
        Resource = "arn:aws:s3:::batch-bucket/*"
      }
    ]
  })
}

# Session Policy
resource "aws_rolesanywhere_profile" "batch_profile" {
  name       = "${var.environment}-batch-profile"
  role_arns  = [aws_iam_role.batch_role.arn]
  enabled    = true
  
  session_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["s3:GetObject", "s3:PutObject"]
        Resource = "arn:aws:s3:::batch-bucket/*"
      }
    ]
  })

  tags = {
    Environment = var.environment
  }

  depends_on = [aws_iam_role.batch_role]
}

# Output
output "trust_anchor_arn" {
  value       = aws_rolesanywhere_trust_anchor.batch_ca.arn
  description = "Trust Anchor ARN"
}

output "profile_arn" {
  value       = aws_rolesanywhere_profile.batch_profile.arn
  description = "Profile ARN"
}

output "batch_role_arn" {
  value       = aws_iam_role.batch_role.arn
  description = "Batch Role ARN"
}

類似サービス比較表 {#比較}

観点 IAM Roles Anywhere GitHub Actions OIDC HashiCorp Vault GCP Workload Identity Federation Azure AD Federated Identity
認証方式 X.509 証明書 OIDC トークン 複数(Cert、AppRole、JWT) OIDC / SAML OIDC / SAML
対応環境 オンプレ・エッジ・他クラウド GitHub Actions + クラウド 広範(複数 IdP 対応) GCP ワークロード Azure ワークロード
短命クレデンシャル 最大 12 時間 GitHub token(1 時間) 可変(設定可能) 可変 可変
PKI 統合 ネイティブ(Trust Anchor) 外部連携必要 ネイティブ 限定的 限定的
CloudTrail 監査 証明書シリアルで一意化 サポート 外部統合 サポート サポート
コスト 無料(Private CA は別途) 無料 有料 / OSS 版無料 無料(GCP 利用料別) 無料(Azure 利用料別)
管理複雑性 中(PKI 管理必要) 高(中央 Vault 管理)
セルフホスト K8s サポート(証明書マウント) 非対応 サポート 非対応 非対応
マルチクラウド 優秀(AWS 外のワークロード向け) GitHub 専用 優秀 GCP 専用 Azure 専用

比較:なぜ IAM Roles Anywhere か

  • OIDC より優位: 社内 OIDC プロバイダーがない環境で、既存 PKI を活用できる
  • Vault より簡潔: AWS IAM ロール・ポリシーを直接使用でき、OIDC プロバイダーの運用不要
  • GCP / Azure より広い: AWS 以外のクラウドからのアクセスにも対応
  • セルフホスト K8s に強い: EKS Pod Identity は EKS 専用だが、Roles Anywhere はセルフホスト K8s もサポート

ベストプラクティス {#bestpractices}

✅ DO(すべき)

  1. Trust Anchor に AWS Private CA を使用する

    • CRL の自動管理・更新が実装される
    • CloudTrail 統合が深い
  2. Subject DN で細粒度制御を実装する

    • 証明書の CN(Common Name)・OU を IAM Condition で制限
    • 不正な証明書の悪用を防止
  3. Session Policy で最小権限を実装する

    • Role 権限 × Session Policy の交差で、最小限の権限のみ付与
    • 権限漏洩時の被害最小化
  4. CRL 検証を有効化する

    • Trust Anchor 設定時に CRL URL を明示的に設定
    • 失効証明書の即座な無効化
  5. CloudTrail で監査ログを記録する

    • 証明書シリアルナンバーで一意性追跡
    • コンプライアンス監査に活用
  6. 証明書ローテーション計画を立てる

    • 毎年 1 回以上の証明書更新スケジュール
    • 有効期限前の更新作業を自動化
  7. 複数の Profile を用途別に分ける

    • Prod / Dev / Test で異なる Profile
    • 本番環境への誤アクセスを防止
  8. 一時認証情報の有効期間を短く設定する

    • バッチジョブは 1 時間以下
    • 長時間実行が必要な場合は定期的に再取得

❌ DON’T(してはいけない)

  1. 一時認証情報を長期保存する

    # ❌ BAD: 認証情報を環境変数に永続化
    echo "export AWS_ACCESS_KEY_ID=..." >> ~/.bashrc
    
    # ✅ GOOD: 認証情報を動的に取得・一時保存
    eval $(aws-rolesanywhere-credential-helper ...)
    
  2. Trust Anchor のリストアップを怠る

    • 不正な Trust Anchor が登録されないか定期確認
    • Unused Trust Anchor を削除
  3. Subject DN マッピングなしで Profile を作成する

    // ❌ BAD: すべてのサーバーが同一 Role を引き受け
    {
      "profileArn": "arn:aws:rolesanywhere:...",
      "roleArns": ["arn:aws:iam::123456789012:role/UniversalRole"]
    }
    
    // ✅ GOOD: Subject DN で制限
    "Condition": {
      "StringEquals": {
        "aws:x509SubjectAltName": "prod-batch-server-01"
      }
    }
    
  4. Session Policy なしで高権限 Role を参照する

    // ❌ BAD: Role の全権限を使用可能
    {
      "roleArns": ["arn:aws:iam::123456789012:role/AdminRole"]
    }
    
    // ✅ GOOD: Session Policy で制限
    {
      "roleArns": ["arn:aws:iam::123456789012:role/AdminRole"],
      "sessionPolicy": {...}  // 最小権限に制限
    }
    
  5. 証明書秘密鍵を平文で保存する

    • 秘密鍵は /etc/pki/rolesanywhere/ など、root のみアクセス可能なディレクトリに配置
    • 秘密鍵のバックアップは暗号化して保管
  6. 認証情報の期限切れに対応しない

    # ❌ BAD: 認証情報の有効期限をチェックしない
    aws s3 ls
    
    # ✅ GOOD: cron で定期的に再取得
    */30 * * * * /usr/local/bin/refresh-rolesanywhere-creds.sh
    
  7. 複数 AWS アカウントでの Role 参照ルールを不明確にする

    • クロスアカウント接続の場合、明示的な IAM Trust Policy を設定
    • Organizations SCP で予期しないクロスアカウント接続を防止

トラブルシューティング {#troubleshooting}

症状 原因 対応
CreateSession API エラー:InvalidCertificate X.509 証明書が Trust Anchor の CA によって署名されていない、または有効期限切れ 証明書の検証:openssl x509 -in cert.pem -text -noout で有効期限・発行者確認
CreateSession API エラー:SourceArnNotFound Trust Anchor / Profile ARN が存在しない、またはリージョンが異なる ARN を確認・リージョンを統一
AssumeRole エラー:NotAssumedByRolesAnywhere IAM Role の Trust Policy が Roles Anywhere を信頼していない Role の Trust Policy に rolesanywhere.amazonaws.com を追加
S3 アクセス エラー:AccessDenied Session Policy または Role Policy が S3 アクション・リソースを許可していない IAM ポリシーを確認・s3:GetObject など必要なアクション追加
CRL 検証失敗:CertificateRevoked 証明書が CRL に含まれている(失効) 新規証明書を再発行・Trust Anchor の CRL URL が最新か確認
Subject DN マッピング失敗 証明書の Subject DN が IAM Condition と一致していない openssl x509 -in cert.pem -noout -subject で DN を確認・IAM Policy の Condition を修正
CloudTrail ログに記録されない CloudTrail が無効、または IAM role が CloudTrail に権限がない CloudTrail を有効化・CloudTrail IAM Role に cloudtrail:PutEvents 権限追加
credential-helper が実行ファイルがない aws-rolesanywhere-credential-helper が PATH に含まれていない which aws-rolesanywhere-credential-helper で確認・インストール or PATH に追加

セキュリティのポイント {#security}

1. 証明書ライフサイクル管理

発行(CA から signed)
    ↓ 有効期間(通常 1-3 年)
    ↓
有効期限切れ予定日(30 日前) → 新規発行・ロールオーバー
    ↓
有効期限切れ → 自動失効・アクセス不可
    ↓
アーカイブ(監査ログ保持 7 年以上)

2. 秘密鍵保護

  • ファイルシステム権限chmod 600 /etc/pki/rolesanywhere/key.pem(root のみ読取)
  • ボリューム暗号化:EBS / データセンターストレージの暗号化
  • HSM 統合:高セキュリティ環境では秘密鍵を HSM に保管

3. CloudTrail 監査

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "AIDAIN...",
    "arn": "arn:aws:iam::123456789012:role/OnPremBatchRole",
    "accountId": "123456789012",
    "sourceArn": "arn:aws:rolesanywhere:ap-northeast-1:123456789012:trust-anchor/f0c72d7e"
  },
  "eventTime": "2026-04-26T10:00:00Z",
  "eventSource": "sts.amazonaws.com",
  "eventName": "AssumeRole",
  "sourceIPAddress": "203.0.113.10",
  "certificateSerialNumber": "0123456789ABCDEF"  // 一意な証明書シリアル
}

4. 不正アクセス検出

CloudWatch Logs Insights で失敗したセッション作成を検出:

fields @timestamp, sourceIPAddress, errorCode
| filter eventSource = "rolesanywhere" and eventName = "CreateSession" and errorCode != "Success"
| stats count() by sourceIPAddress, errorCode
| filter count > 5

2025-2026 最新動向 {#latest}

1. Post-Quantum Digital Certificates(2026 新機能)

概要:量子コンピュータによる暗号解読に耐性を持つ POST-QUANTUM 暗号(NIST 標準化)に対応

Impact

  • 既存 RSA 2048 bit 証明書の脆弱性に備える
  • 2030 年以降の NIST 推奨として PQC 移行
  • AWS Private CA が CRYSTALS-Kyber / CRYSTALS-Dilithium をサポート予定

2. Subject DN Condition 拡張

概能:証明書の OU / O / C などより多くの属性で細粒度制御

{
  "Condition": {
    "StringEquals": {
      "aws:x509Subject.O": "MyCompany",
      "aws:x509Subject.OU": "Production",
      "aws:x509Subject.CN": "batch-server-01"
    }
  }
}

3. CRL 検証自動化の強化

概能:CRL サーバーが一時的に応答不可な場合の graceful handling

  • CRL キャッシュの自動更新
  • OCSP(Online Certificate Status Protocol)対応検討

4. EKS Pod Identity との統合強化

概能:セルフホスト K8s で Pod に証明書自動マウント、Roles Anywhere 認証を自動化

apiVersion: v1
kind: Pod
metadata:
  annotations:
    rolesanywhere.amazonaws.com/trust-anchor-arn: "arn:aws:rolesanywhere:..."
    rolesanywhere.amazonaws.com/profile-arn: "arn:aws:rolesanywhere:..."

5. Cross-Account Roles Anywhere Management

概能:Organizations 配下の複数アカウントで Roles Anywhere リソースを一元管理

  • Firewall Manager で Trust Anchor / Profile の集約配置
  • SCPs で Roles Anywhere 利用を制限

学習リソース・参考文献 {#resources}

公式ドキュメント

  1. IAM Roles Anywhere User Guide https://docs.aws.amazon.com/rolesanywhere/latest/userguide/

  2. IAM Roles Anywhere API Reference https://docs.aws.amazon.com/rolesanywhere/latest/APIReference/

  3. AWS Security Blog - IAM Roles Anywhere https://aws.amazon.com/blogs/security/tag/iam-roles-anywhere/

  4. AWS Certificate Manager Private CA Documentation https://docs.aws.amazon.com/acm-pca/latest/userguide/

  5. IAM Best Practices https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html

  6. CloudTrail User Guide https://docs.aws.amazon.com/awscloudtrail/latest/userguide/

  7. AWS Security Reference Architecture https://docs.aws.amazon.com/security/

  8. Well-Architected Framework - Security Pillar https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/

OSS / ベンダー資料

  1. SPIFFE / SPIRE(Open Standards for Identity) https://spiffe.io/docs/latest/spiffe/overview/

  2. HashiCorp Vault Documentation https://www.vaultproject.io/docs

  3. OpenSSL X.509 Certificate Guide https://www.openssl.org/docs/man1.1.1/man1/x509.html

  4. RFC 5280 - Internet X.509 Public Key Infrastructure https://tools.ietf.org/html/rfc5280

  5. NIST Post-Quantum Cryptography Standardization https://csrc.nist.gov/projects/post-quantum-cryptography/

技術ブログ・チュートリアル

  • AWS Builders - Roles Anywhere で多環境対応
  • Medium - IAM Roles Anywhere Tutorials
  • dev.to - AWS IAM Roles Anywhere 実装例

実装例・チェックリスト {#checklist}

実装フェーズチェックリスト

  • [ ] AWS Private CA を作成 or 既存 CA 証明書を用意
  • [ ] Trust Anchor を作成(CA 登録)
  • [ ] IAM Role を作成(Trust Policy で Roles Anywhere を信頼)
  • [ ] IAM Permission Policy を設定(必要な AWS リソースアクセスを許可)
  • [ ] Profile を作成(Role + Session Policy)
  • [ ] X.509 証明書をエンドポイント(サーバー / CI/CD)に配布
  • [ ] aws-rolesanywhere-credential-helper をインストール
  • [ ] CreateSession テスト(手動で認証情報取得)
  • [ ] AWS CLI / SDK 統合テスト
  • [ ] CloudTrail ログを確認(証明書シリアル記録)
  • [ ] 本番環境へのロールアウト

セキュリティチェックリスト

  • [ ] 秘密鍵のアクセス権限を 600(root のみ)に設定
  • [ ] 秘密鍵をバージョン管理に含めない(.gitignore)
  • [ ] CRL URL を設定・定期更新確認
  • [ ] Subject DN Condition で細粒度制限を実装
  • [ ] Session Policy で最小権限を実装
  • [ ] CloudTrail ログ保持期間を設定(監査要件に従う)
  • [ ] 証明書有効期限切れ通知を自動化(30 日前)
  • [ ] 失効証明書からのアクセス試行を CloudWatch Alarms で監視
  • [ ] Roles Anywhere リソース(Trust Anchor / Profile)の一覧を定期確認

運用チェックリスト

  • [ ] 証明書ローテーション計画を年 1 回以上実施
  • [ ] 不要な Trust Anchor / Profile を定期削除
  • [ ] CloudTrail ログを定期分析(異常検知)
  • [ ] IAM Access Analyzer で external access を確認
  • [ ] 従業員退職時の秘密鍵回収・破棄プロセス確立
  • [ ] Disaster Recovery / バックアップ戦略(CA 秘密鍵)

まとめ {#summary}

AWS IAM Roles Anywhere は、オンプレミス・エッジ・マルチクラウド環境から AWS リソースへのセキュアアクセスを実現する無料サービス です。

Core Takeaways

  1. X.509 証明書ベース認証:長期アクセスキー廃止、既存 PKI 活用
  2. 一時認証情報(最大 12 時間):短命クレデンシャル、自動失効
  3. IAM ロール統一:AWS ネイティブのポリシー・ロール管理
  4. CloudTrail 監査:証明書シリアルで一意性追跡
  5. 無料:追加コストなし(Private CA は別途)

採用すべき環境

  • オンプレミス環境が存在し、AWS アクセスを安全化したい
  • 社内 OIDC プロバイダーがない環境での認証統一
  • 既存 PKI 基盤(ADCS / Vault)をそのまま活用したい
  • セルフホスト Kubernetes での IAM 統合が必要
  • マルチクラウド環境(AWS ハブ)を構築している

導入時の注意点

  • PKI 管理・証明書ローテーション運用が別途必要
  • Trust Anchor / Profile / IAM Role の設定複雑性
  • 秘密鍵の厳格な保護・監査が必須
  • Subject DN マッピング設定の慎重性

次のステップ

  1. AWS Private CA の導入 or 既存 CA 統合検討
  2. Proof of Concept(PoC)での小規模テスト
  3. 証明書ライフサイクル管理プロセス確立
  4. 本番ロールアウト・監視・アラーム設定

IAM Roles Anywhere により、オンプレミス環境と AWS クラウドを安全に統合し、ハイブリッドクラウド時代の認証基盤を構築できます。


最終更新:2026-04-26
バージョン:v2.0