첫 번째 인증된 에이전트 빌드
이 시작하기 자습서에서는 Amazon Bedrock AgentCore 자격 증명을 사용하여 처음부터 완전히 인증된 에이전트를 구축하는 방법을 안내하고 에이전트 애플리케이션에서 자격 증명 기능을 구현하는 방법을 안내합니다. 개발 환경을 설정하고, Cognito를 사용하여 인증 인프라를 생성하고, 에이전트를 AgentCore 런타임에 배포하고, 전체 인증 워크플로를 테스트하는 방법을 알아봅니다.
이 자습서를 마치면 OAuth2 흐름을 통해 사용자를 인증하고, 액세스 토큰을 안전하게 획득하고, 전체 자격 증명 관리 수명 주기를 시연할 수 있는 완전히 배포된 에이전트를 갖게 됩니다. 에이전트는 적절한 IAM 권한으로 AgentCore 런타임에서 실행되어 통합 기능을 시연하고 테스트할 수 있는 테스트 랩 환경을 생성합니다.
주제
사전 조건
시작하기 전에 다음을 갖추었는지 확인하세요.
-
적절한 권한이 있는 AWS 계정
-
Python 3.10 이상 설치됨
-
최신 AWS CLI 및
jq설치됨 -
Node.js 18+ 설치됨( AgentCore CLI용)
-
AWS 구성된 자격 증명 및 리전(
aws configure)
이 자습서에서는 OAuth 2.0 권한 부여 서버가 있어야 합니다. 없는 경우 1단계는 Amazon Cognito 사용자 풀을 사용하여 사용자를 위해 하나를 생성합니다. 클라이언트 ID, 클라이언트 보안 암호 및 사용자가 구성된 OAuth 2.0 권한 부여 서버가 있는 경우 2단계로 진행할 수 있습니다. 이 권한 부여 서버는 에이전트에게 아웃바운드 OAuth 2.0 액세스 토큰을 부여하는 권한을 나타내는 리소스 자격 증명 공급자 역할을 합니다.
SDK 및 종속성 설치
이 가이드의 폴더를 만들고 Python 가상 환경을 생성한 다음 AgentCore SDK 및 AWS Python SDK(boto3)를 설치합니다.
mkdir agentcore-identity-quickstart cd agentcore-identity-quickstart python3 -m venv .venv source .venv/bin/activate pip install bedrock-agentcore boto3 strands-agents pyjwt
또한 다음 콘텐츠로 requirements.txt 파일을 생성합니다. 이는 나중에 AgentCore 배포 도구에서 사용됩니다.
bedrock-agentcore boto3 pyjwt strands-agents
1단계: Cognito 사용자 풀 생성(선택 사항)
이 자습서에는 OAuth 2.0 권한 부여 서버가 필요합니다. 테스트에 사용할 수 있는 인스턴스가 없거나 테스트를 권한 부여 서버와 별도로 유지하려는 경우이 스크립트는 자격 AWS 증명을 사용하여 권한 부여 서버로 사용할 Amazon Cognito 인스턴스를 설정합니다. 스크립트는 다음을 생성합니다.
-
Cognito 사용자 풀
-
OAuth 2.0 클라이언트 및 해당 사용자 풀의 클라이언트 보안 암호
-
해당 Cognito 사용자 풀의 테스트 사용자 및 암호
Cognito 사용자 풀 AgentCoreIdentityQuickStartPool을 삭제하면 연결된 client_id 및 사용자도 삭제됩니다.
이 스크립트를 create_cognito.sh로 저장하고 명령줄에서 실행하거나 스크립트를 명령줄에 붙여 넣을 수 있습니다.
#!/bin/bash REGION=$(aws configure get region) # Create user pool USER_POOL_ID=$(aws cognito-idp create-user-pool \ --pool-name AgentCoreIdentityQuickStartPool \ --query 'UserPool.Id' \ --no-cli-pager \ --output text) # Create user pool domain DOMAIN_NAME="agentcore-quickstart-$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 5)" aws cognito-idp create-user-pool-domain \ --domain $DOMAIN_NAME \ --no-cli-pager \ --user-pool-id $USER_POOL_ID > /dev/null # Create user pool client with secret and hosted UI settings CLIENT_RESPONSE=$(aws cognito-idp create-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-name AgentCoreQuickStart \ --generate-secret \ --allowed-o-auth-flows "code" \ --allowed-o-auth-scopes "openid" "profile" "email" \ --allowed-o-auth-flows-user-pool-client \ --supported-identity-providers "COGNITO" \ --query 'UserPoolClient.{ClientId:ClientId,ClientSecret:ClientSecret}' \ --output json) CLIENT_ID=$(echo $CLIENT_RESPONSE | jq -r '.ClientId') CLIENT_SECRET=$(echo $CLIENT_RESPONSE | jq -r '.ClientSecret') # Generate random username and password USERNAME="AgentCoreTestUser$(printf "%04d" $((RANDOM % 10000)))" PASSWORD="$(LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?' < /dev/urandom | head -c 16)$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 1)" # Create user with permanent password aws cognito-idp admin-create-user \ --user-pool-id $USER_POOL_ID \ --username $USERNAME \ --output text > /dev/null aws cognito-idp admin-set-user-password \ --user-pool-id $USER_POOL_ID \ --username $USERNAME \ --password $PASSWORD \ --output text > /dev/null \ --permanent # Get region ISSUER_URL="https://cognito-idp.$REGION.amazonaws.com/$USER_POOL_ID/.well-known/openid-configuration" HOSTED_UI_URL="https://$DOMAIN_NAME.auth.$REGION.amazoncognito.com" # Output results echo "User Pool ID: $USER_POOL_ID" echo "Client ID: $CLIENT_ID" echo "Client Secret: $CLIENT_SECRET" echo "Issuer URL: $ISSUER_URL" echo "Hosted UI URL: $HOSTED_UI_URL" echo "Test User: $USERNAME" echo "Test Password: $PASSWORD" echo "" echo "# Copy and paste these exports to set environment variables for later use:" echo "export USER_POOL_ID='$USER_POOL_ID'" echo "export CLIENT_ID='$CLIENT_ID'" echo "export CLIENT_SECRET='$CLIENT_SECRET'" echo "export ISSUER_URL='$ISSUER_URL'" echo "export HOSTED_UI_URL='$HOSTED_UI_URL'" echo "export COGNITO_USERNAME='$USERNAME'" echo "export COGNITO_PASSWORD='$PASSWORD'"
2단계: 자격 증명 공급자 생성
자격 증명 공급자는 에이전트가 외부 서비스에 액세스하는 방법입니다. 자격 증명 공급자를 생성하고 권한 부여 서버의 OAuth 2.0 클라이언트로 구성합니다.
자체 권한 부여 서버를 사용하는 경우 권한 부여 서버의 CLIENT_SECRET 적절한 값으로 환경 변수 ISSUER_URL , 및 CLIENT_ID를 설정합니다. 이전 스크립트를 사용하여 Cognito로 권한 부여 서버를 생성하는 경우 출력의 EXPORT 문을 터미널로 복사하여 환경 변수를 설정합니다.
이 자격 증명 공급자는 에이전트의 코드에서 사용자를 대신하여 작업할 액세스 토큰을 가져오는 데 사용됩니다.
예
2.5단계: OAuth 2.0 권한 부여 서버에 콜백 URL 추가
무단 리디렉션을 방지하려면 CreateOauth2CredentialProvider 또는 GetOauth2CredentialProvider에서 검색된 콜백 URL을 OAuth 2.0 권한 부여 서버에 추가합니다.
이전 스크립트를 사용하여 Cognito로 권한 부여 서버를 생성하는 경우 출력의 EXPORT 문을 터미널로 복사하여 환경 변수를 설정하고 Cognito 사용자 풀 클라이언트를 OAuth2 자격 증명 공급자 콜백 URL로 업데이트합니다.
#!/bin/bash aws cognito-idp update-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-id $CLIENT_ID \ --client-name AgentCoreQuickStart \ --allowed-o-auth-flows "code" \ --allowed-o-auth-scopes "openid" "profile" "email" \ --allowed-o-auth-flows-user-pool-client \ --supported-identity-providers "COGNITO" \ --callback-urls "$OAUTH2_CALLBACK_URL"
3단계: OAuth 2.0 흐름을 시작하는 샘플 에이전트 생성
이 단계에서는 사용자를 대신하여 작업할 토큰을 가져오기 위해 OAuth 2.0 권한 부여 흐름을 시작하는 에이전트를 생성합니다. 간소화를 위해 에이전트는 사용자를 대신하여 외부 서비스를 실제로 호출하지 않지만 테스트 사용자를 대신하여 작업하는 데 동의했음을 증명합니다.
에이전트 코드
라는 파일을 생성하고이 코드를 agentcoreidentityquickstart.py 저장합니다.
""" AgentCore Identity Outbound Token Agent This agent demonstrates the USER_FEDERATION OAuth 2.0 flow. It handles the OAuth 2.0 user consent flow and inspects the resulting OAuth 2.0 access token. """ from bedrock_agentcore.runtime import BedrockAgentCoreApp from bedrock_agentcore.identity import requires_access_token import asyncio import jwt import logging app = BedrockAgentCoreApp() logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def decode_jwt(token): try: decoded = jwt.decode(token, options={"verify_signature": False}) return decoded except Exception as e: return {"error": f"Error decoding JWT: {str(e)}"} class StreamingQueue: def __init__(self): self.finished = False self.queue = asyncio.Queue() async def put(self, item): await self.queue.put(item) async def finish(self): self.finished = True await self.queue.put(None) async def stream(self): while True: item = await self.queue.get() if item is None and self.finished: break yield item queue = StreamingQueue() async def handle_auth_url(url): await queue.put(f"Authorization URL, please copy to your preferred browser: {url}") @requires_access_token( provider_name="AgentCoreIdentityQuickStartProvider", scopes=["openid"], auth_flow="USER_FEDERATION", on_auth_url=handle_auth_url, # streams authorization URL to client force_authentication=True, callback_url='insert_oauth2_callback_url_for_session_binding', ) async def introspect_with_decorator(*, access_token: str): """Introspect token using decorator""" logger.info("Inside introspect_with_decorator - decorator succeeded") await queue.put({ "message": "Successfully received an access token to act on behalf of your user!", "token_claims": decode_jwt(access_token), "token_length": len(access_token), "token_preview": f"{access_token[:50]}...{access_token[-10:]}" }) await queue.finish() @app.entrypoint async def agent_invocation(payload, context): """Handler that uses only the decorator approach""" logger.info("Agent invocation started") # Start the agent task and immediately begin streaming task = asyncio.create_task(introspect_with_decorator()) # Stream items as they come in async for item in queue.stream(): yield item # Wait for task completion await task if __name__ == "__main__": app.run()
참고
세션 바인딩을 처리하기 위한 샘플 로컬 콜백 서버 구현은 oauth2_callback_server.py
4단계: 에이전트를 AgentCore 런타임에 배포
AgentCore 런타임에서이 에이전트를 호스팅합니다. AgentCore CLI를 사용하여 쉽게이 작업을 수행할 수 있습니다.
터미널에서 AgentCore CLI를 설치하고 새 프로젝트를 생성합니다.
npm install -g @aws/agentcore agentcore create --name IdentityQuickstart --defaults
에이전트 스크립트를 프로젝트의 에이전트 디렉터리에 복사하여 기본 에이전트를 바꿉니다.
cp agentcoreidentityquickstart.py IdentityQuickstart/app/IdentityQuickstart/main.py
또한 모든 종속성이 배포에 포함되도록 요구 사항 파일을 에이전트 디렉터리에 복사합니다.
cp requirements.txt IdentityQuickstart/app/IdentityQuickstart/
그런 다음 프로젝트를 배포합니다.
cd IdentityQuickstart agentcore deploy
CLI는 AWS CDK 스택을 합성하고 에이전트를 AgentCore 런타임에 배포합니다. 이 작업은 약 2~3분이 걸립니다.
토큰 볼트 및 클라이언트 보안 암호에 액세스할 수 있도록 에이전트의 IAM 정책 업데이트
AgentCore CLI는 배포 중에 에이전트의 실행 역할을 생성하지만 역할에 토큰 볼트 액세스 권한이 자동으로 포함되지 않습니다. 에이전트가 런타임에 OAuth 2.0 토큰을 검색할 수 있도록 추가 정책을 연결해야 합니다.
이 스크립트는 AWS CLI에서 계정과 리전을 검색하고, CloudFormation 스택에서 에이전트의 실행 역할을 찾고, 적절한 정책을 연결합니다. 이 스크립트를 복사하여 붙여넣거나 파일에 저장하고 실행할 수 있습니다.
#!/bin/bash # Get account and region from AWS CLI AWS_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) REGION=$(aws configure get region) # Get execution role from CloudFormation stack outputs EXECUTION_ROLE=$(aws cloudformation describe-stack-resources \ --stack-name AgentCore-IdentityQuickstart-prod \ --query "StackResources[?ResourceType=='AWS::IAM::Role'].PhysicalResourceId" \ --output text | head -1) echo "Parsed values:" echo "Execution Role: $EXECUTION_ROLE" echo "Account: $AWS_ACCOUNT" echo "Region: $REGION" # Create the policy document with proper variable substitution cat > agentcore-identity-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AccessTokenVault", "Effect": "Allow", "Action": [ "bedrock-agentcore:GetResourceOauth2Token", "secretsmanager:GetSecretValue" ], "Resource": ["arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default/workload-identity/*", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default/oauth2credentialprovider/AgentCoreIdentityQuickStartProvider", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default", "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default", "arn:aws:secretsmanager:$REGION:$AWS_ACCOUNT:secret:bedrock-agentcore-identity!default/oauth2/AgentCoreIdentityQuickStartProvider*" ] } ] } EOF # Create the policy POLICY_ARN=$(aws iam create-policy \ --policy-name AgentCoreIdentityQuickStartPolicy$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 4) \ --policy-document file://agentcore-identity-policy.json \ --query 'Policy.Arn' \ --output text) # Extract role name from ARN and attach policy ROLE_NAME=$(echo $EXECUTION_ROLE | awk -F'/' '{print $NF}') aws iam attach-role-policy \ --role-name $ROLE_NAME \ --policy-arn $POLICY_ARN echo "Policy created and attached: $POLICY_ARN" # Cleanup rm agentcore-identity-policy.json
5단계: 에이전트 간접 호출
이제 모두 설정되었으므로 에이전트를 호출할 수 있습니다. 이 데모에서는 agentcore invoke 명령과 IAM 자격 증명을 사용합니다. IAM 인증을 사용할 때 --user-id 및 --session-id 인수를 전달해야 합니다.
agentcore invoke "TestPayload" --runtime IdentityQuickstart --user-id "SampleUserID" --session-id "ALongThirtyThreeCharacterMinimumSessionIdYouCanChangeThisAsYouNeed"
그러면 에이전트가 agentcore invoke 명령에 URL을 반환합니다. 해당 URL을 복사하여 원하는 브라우저에 붙여넣으면 권한 부여 서버의 로그인 페이지로 리디렉션됩니다. --user-id 파라미터는 AgentCore 자격 증명에 제공하는 사용자 ID입니다. --session-id 파라미터는 세션 ID로, 33자 이상이어야 합니다.
중요
--user-id 파라미터는 인증된 최종 사용자 자격 증명에 대해 확인하지 않고 userId를 불투명 문자열로 처리하는 GetWorkloadAccessTokenForUserId API 경로를 사용합니다. 이는 사용 가능한 IdP 토큰이 없는 빠른 시작 및 개발 시나리오에 적합합니다. 최종 사용자를 식별하는 JWT가 있는 프로덕션 배포의 경우 토큰의 발급자, 서명 및 만료를 검증하는 JWT 기반 인증 경로(GetWorkloadAccessTokenForJWT)를 대신 사용합니다. 자세한 내용은 워크로드 액세스 토큰 가져오기를 참조하세요.
브라우저에 메시지가 표시되면 권한 부여 서버의 사용자 이름과 암호를 입력하거나 구성한 기본 인증 방법을 사용합니다. 1단계의 스크립트를 사용하여 Cognito 인스턴스를 생성한 경우 터미널 기록에서 이를 검색할 수 있습니다.
브라우저는 세션 바인딩 흐름를 처리하는 구성된 OAuth2 콜백 URL로 리디렉션해야 합니다. OAuth2 콜백 서버가 권한 부여 상태를 나타내는 명확한 성공 및 오류 응답을 제공하는지 확인합니다.
참고
권한 부여를 완료하지 않고 호출을 중단하는 경우 새 세션 ID( --session-id 파라미터)를 사용하여 새 URL을 요청해야 할 수 있습니다.
디버깅
오류나 예기치 않은 동작이 발생하면 에이전트의 출력이 Amazon CloudWatch logs에 캡처됩니다. 를 실행하면 로그 테일링 명령이 제공됩니다agentcore deploy.
정리
작업을 완료한 후 프로젝트 디렉터리agentcore deploy에서 agentcore remove all 및를 실행하여 배포된 AgentCore 런타임 리소스를 제거합니다. 그런 다음 Amazon Cognito 사용자 풀을 삭제하고, 생성한 IAM 정책을 분리 및 삭제하고, 자격 증명 공급자를 삭제합니다.
보안 모범 사례
자격 증명 정보로 작업하는 경우:
-
에이전트 코드에 자격 증명을 하드코딩하지 마십시오.
-
환경 변수 또는 Amazon SageMaker AI를 사용하여 민감한 정보 확인
-
IAM 권한을 구성할 때 최소 권한 원칙 적용
-
외부 서비스의 자격 증명을 정기적으로 교체
-
액세스 로그를 감사하여 에이전트 활동 모니터링
-
인증 실패에 대한 적절한 오류 처리 구현