

# Bangun agen otentikasi pertama Anda
<a name="identity-getting-started-cognito"></a>

Tutorial memulai ini memandu Anda melalui pembuatan agen otentikasi lengkap dari bawah ke atas menggunakan Amazon Bedrock AgentCore Identity dan akan membantu Anda memulai dengan menerapkan fitur identitas dalam aplikasi agen Anda. Anda akan mempelajari cara mengatur lingkungan pengembangan, membuat infrastruktur otentikasi dengan Cognito, menyebarkan agen Anda AgentCore ke Runtime, dan menguji alur kerja otentikasi lengkap.

Pada akhir tutorial ini, Anda akan memiliki agen yang sepenuhnya digunakan yang dapat mengautentikasi pengguna melalui aliran OAuth2, mendapatkan token akses dengan aman, dan mendemonstrasikan siklus hidup manajemen identitas lengkap. Agen Anda akan berjalan di AgentCore Runtime dengan izin IAM yang tepat, menciptakan lingkungan lab pengujian tempat Anda dapat mendemonstrasikan dan menguji kemampuan integrasi.

**Topics**
+ [Prasyarat](#identity-quick-start-prerequisites)
+ [Langkah 1: Buat kumpulan pengguna Cognito (Opsional)](#identity-quick-start-cognito)
+ [Langkah 2: Buat penyedia kredensi](#identity-quick-start-credential-provider)
+ [Langkah 2.5: Tambahkan URL callback ke server otorisasi OAuth 2.0 Anda](#identity-update-credential-provider)
+ [Langkah 3: Buat agen sampel yang memulai aliran OAuth 2.0](#identity-quick-start-agent)
+ [Langkah 4: Menyebarkan agen ke AgentCore Runtime](#identity-quick-start-deploy)
+ [Langkah 5: Panggil agen](#identity-quick-start-invoke)
+ [Bersihkan](#identity-quick-start-cleanup)
+ [Praktik terbaik keamanan](#identity-quick-start-security)

## Prasyarat
<a name="identity-quick-start-prerequisites"></a>

Sebelum Anda mulai, pastikan Anda memiliki:
+  AWS Akun dengan izin yang sesuai
+ Python 3.10\+ diinstal
+  AWS CLI terbaru dan diinstal `jq`
+ Node.js 18\+ diinstal (untuk AgentCore CLI)
+  AWS kredensi dan wilayah dikonfigurasi () `aws configure`

Tutorial ini mengharuskan Anda memiliki server otorisasi OAuth 2.0. Jika Anda tidak memilikinya, Langkah 1 akan membuatnya untuk Anda menggunakan kumpulan pengguna Amazon Cognito. Jika Anda memiliki server otorisasi OAuth 2.0 dengan id klien, rahasia klien, dan pengguna yang dikonfigurasi, Anda dapat melanjutkan ke langkah 2. Server otorisasi ini akan bertindak sebagai penyedia kredensi sumber daya, mewakili otoritas yang memberikan agen token akses OAuth 2.0 keluar.

### Instal SDK dan dependensi
<a name="identity-quick-start-install"></a>

Buat folder untuk panduan ini, buat lingkungan virtual Python, dan instal SDK dan AWS Python AgentCore 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
```

Juga buat `requirements.txt` file dengan konten berikut. Ini akan digunakan nanti oleh alat AgentCore penyebaran.

```
bedrock-agentcore
boto3
pyjwt
strands-agents
```

## Langkah 1: Buat kumpulan pengguna Cognito (Opsional)
<a name="identity-quick-start-cognito"></a>

Tutorial ini membutuhkan server otorisasi OAuth 2.0. Jika Anda tidak memiliki satu yang tersedia untuk pengujian, atau jika Anda ingin memisahkan pengujian Anda dari server otorisasi Anda, skrip ini akan menggunakan AWS kredensi Anda untuk menyiapkan instans Amazon Cognito untuk Anda gunakan sebagai server otorisasi. Script akan membuat:
+ Kumpulan pengguna Cognito
+ Klien OAuth 2.0, dan rahasia klien untuk kumpulan pengguna itu
+ Pengguna uji dan kata sandi di kumpulan pengguna Cognito itu

Menghapus AgentCoreIdentityQuickStartPool kumpulan pengguna Cognito akan menghapus client\_id dan pengguna terkait juga.

Anda dapat memilih untuk menyimpan skrip ini sebagai create\_cognito.sh dan menjalankannya dari baris perintah Anda, atau menempelkan skrip ke baris perintah Anda.

```
#!/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'"
```

## Langkah 2: Buat penyedia kredensi
<a name="identity-quick-start-credential-provider"></a>

Penyedia kredensi adalah cara agen Anda mengakses layanan eksternal. Buat penyedia kredensi dan konfigurasikan dengan klien OAuth 2.0 untuk server otorisasi Anda.

Jika Anda menggunakan server otorisasi Anda sendiri, atur variabel lingkungan `ISSUER_URL``CLIENT_ID`, dan `CLIENT_SECRET` dengan nilai yang sesuai dari server otorisasi Anda. Jika Anda menggunakan skrip sebelumnya untuk membuat server otorisasi untuk Anda dengan Cognito, salin pernyataan EXPORT dari output ke terminal Anda untuk mengatur variabel lingkungan.

Penyedia kredensi ini akan digunakan oleh kode agen Anda untuk mendapatkan token akses untuk bertindak atas nama pengguna Anda.

**Example**  

1. Jika Anda memiliki proyek AgentCore CLI, Anda dapat menambahkan penyedia kredensi menggunakan CLI. CLI akan membuat penyedia selama penerapan.

   ```
   agentcore add credential \
     --name AgentCoreIdentityQuickStartProvider \
     --type oauth \
     --discovery-url "$ISSUER_URL" \
     --client-id "$CLIENT_ID" \
     --client-secret "$CLIENT_SECRET"
   ```

   Penyedia kredensi akan dibuat saat Anda menjalankan `agentcore deploy` di Langkah 4. Perhatikan URL callback dari output deploy.

1. 

   ```
   #!/bin/bash
   # please note the expected ISSUER_URL format for Bedrock AgentCore is the full url, including .well-known/openid-configuration
   OAUTH2_CREDENTIAL_PROVIDER_RESPONSE=$(aws bedrock-agentcore-control create-oauth2-credential-provider \
     --name "AgentCoreIdentityQuickStartProvider" \
     --credential-provider-vendor "CustomOauth2" \
     --oauth2-provider-config-input '{
       "customOauth2ProviderConfig": {
         "oauthDiscovery": {
           "discoveryUrl": "'$ISSUER_URL'"
         },
         "clientId": "'$CLIENT_ID'",
         "clientSecret": "'$CLIENT_SECRET'"
       }
     }' \
     --output json)
   
   OAUTH2_CALLBACK_URL=$(echo $OAUTH2_CREDENTIAL_PROVIDER_RESPONSE | jq -r '.callbackUrl')
   
   echo "OAuth2 Callback URL: $OAUTH2_CALLBACK_URL"
   ```

## Langkah 2.5: Tambahkan URL callback ke server otorisasi OAuth 2.0 Anda
<a name="identity-update-credential-provider"></a>

Untuk mencegah pengalihan yang tidak sah, tambahkan URL panggilan balik yang diambil dari [CreateOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateOauth2CredentialProvider.html)atau [GetOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_GetOauth2CredentialProvider.html)ke server otorisasi OAuth 2.0 Anda.

Jika Anda menggunakan skrip sebelumnya untuk membuat server otorisasi dengan Cognito, salin pernyataan EXPORT dari output ke terminal Anda untuk mengatur variabel lingkungan dan memperbarui klien kumpulan pengguna Cognito dengan URL panggilan balik penyedia kredensi OAuth2.

```
#!/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"
```

## Langkah 3: Buat agen sampel yang memulai aliran OAuth 2.0
<a name="identity-quick-start-agent"></a>

Pada langkah ini, kami akan membuat agen yang memulai alur otorisasi OAuth 2.0 untuk mendapatkan token untuk bertindak atas nama pengguna. Untuk mempermudah, agen tidak akan melakukan panggilan aktual ke layanan eksternal atas nama pengguna, tetapi akan membuktikan kepada kami bahwa ia telah memperoleh persetujuan untuk bertindak atas nama pengguna uji kami.

### Kode agen
<a name="identity-quick-start-agent-code"></a>

Buat file bernama`agentcoreidentityquickstart.py`, dan simpan kode ini.

```
"""
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()
```

**catatan**  
[Untuk contoh implementasi server callback lokal untuk menangani [pengikatan sesi](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html), lihat oauth2\_callback\_server.py](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py) 

## Langkah 4: Menyebarkan agen ke AgentCore Runtime
<a name="identity-quick-start-deploy"></a>

Kami akan meng-host agen ini di AgentCore Runtime. Kita dapat melakukan ini dengan mudah dengan AgentCore CLI.

Dari terminal Anda, instal AgentCore CLI dan buat proyek baru:

```
npm install -g @aws/agentcore
agentcore create --name IdentityQuickstart --defaults
```

Salin skrip agen Anda ke direktori agen proyek, menggantikan agen default:

```
cp agentcoreidentityquickstart.py IdentityQuickstart/app/IdentityQuickstart/main.py
```

Salin juga file persyaratan Anda ke direktori agen untuk memastikan semua dependensi disertakan dalam penerapan:

```
cp requirements.txt IdentityQuickstart/app/IdentityQuickstart/
```

Kemudian terapkan proyek Anda:

```
cd IdentityQuickstart
agentcore deploy
```

CLI mensintesis tumpukan AWS CDK dan menyebarkan agen Anda ke Runtime. AgentCore Ini membutuhkan waktu sekitar 2-3 menit.

### Perbarui kebijakan IAM agen untuk dapat mengakses brankas token, dan rahasia klien
<a name="identity-quick-start-iam-policy"></a>

 AgentCore CLI membuat peran eksekusi agen selama penerapan, tetapi peran tersebut tidak secara otomatis menyertakan izin untuk akses token vault. Anda perlu melampirkan kebijakan tambahan untuk memungkinkan agen mengambil token OAuth 2.0 saat runtime.

Skrip ini mengambil akun dan wilayah Anda dari AWS CLI, menemukan peran eksekusi agen dari CloudFormation tumpukan, dan melampirkan kebijakan yang sesuai. Anda dapat menyalin dan menempelkan skrip ini, atau menyimpannya ke file dan menjalankannya.

```
#!/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
```

## Langkah 5: Panggil agen
<a name="identity-quick-start-invoke"></a>

Sekarang ini semua sudah diatur, Anda dapat memanggil agen. Untuk demo ini, kami akan menggunakan `agentcore invoke` perintah dan kredensi IAM kami. Kita harus meneruskan `--session-id` argumen `--user-id` dan saat menggunakan otentikasi IAM.

```
agentcore invoke "TestPayload" --runtime IdentityQuickstart --user-id "SampleUserID" --session-id "ALongThirtyThreeCharacterMinimumSessionIdYouCanChangeThisAsYouNeed"
```

Agen kemudian akan mengembalikan URL ke `agentcore invoke` perintah Anda. Salin dan tempel URL tersebut ke browser pilihan Anda, dan Anda kemudian akan diarahkan ke halaman login server otorisasi Anda. `--user-id`Parameternya adalah ID pengguna yang Anda presentasikan ke AgentCore Identity. `--session-id`Parameternya adalah ID sesi, yang panjangnya minimal 33 karakter.

**penting**  
`--user-id`Parameter menggunakan jalur `GetWorkloadAccessTokenForUserId` API, yang memperlakukan userID sebagai string buram tanpa memverifikasinya terhadap identitas pengguna akhir yang diautentikasi. Ini sesuai untuk skenario quickstart dan pengembangan di mana Anda tidak memiliki token IDP yang tersedia. Untuk penerapan produksi di mana Anda memiliki JWT yang mengidentifikasi pengguna akhir, gunakan jalur JWT-based otentikasi (`GetWorkloadAccessTokenForJWT`) sebagai gantinya, yang memvalidasi penerbit token, tanda tangan, dan kedaluwarsa. Untuk informasi selengkapnya, lihat [Mendapatkan token akses beban kerja](get-workload-access-token.md).

Masukkan nama pengguna dan kata sandi untuk pengguna Anda di server otorisasi Anda saat diminta di browser Anda, atau gunakan metode otentikasi pilihan yang telah Anda konfigurasikan. Jika Anda menggunakan skrip dari Langkah 1 untuk membuat instance Cognito, Anda dapat mengambil ini dari riwayat terminal Anda.

[Browser Anda harus mengarahkan ulang ke URL callback OAuth2 yang dikonfigurasi, yang menangani alur pengikatan sesi.](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html) Pastikan server callback OAuth2 Anda memberikan respons keberhasilan dan kesalahan yang jelas untuk menunjukkan status otorisasi.

**catatan**  
Jika Anda mengganggu pemanggilan tanpa menyelesaikan otorisasi, Anda mungkin perlu meminta URL baru menggunakan ID sesi baru (parameter). `--session-id`

### Debugging
<a name="identity-quick-start-debugging"></a>

Jika Anda mengalami kesalahan atau perilaku tak terduga, output agen akan ditangkap di CloudWatch log Amazon. Perintah log tailing disediakan setelah Anda menjalankan`agentcore deploy`.

## Bersihkan
<a name="identity-quick-start-cleanup"></a>

Setelah selesai, jalankan `agentcore remove all` dan kemudian `agentcore deploy` dari direktori proyek Anda untuk merobohkan sumber daya AgentCore Runtime yang diterapkan. Kemudian hapus kumpulan pengguna Amazon Cognito, lepaskan dan hapus kebijakan IAM yang Anda buat, dan hapus penyedia kredensialnya.

## Praktik terbaik keamanan
<a name="identity-quick-start-security"></a>

Saat bekerja dengan informasi identitas:

1.  **Jangan pernah membuat hardcode kredensi** dalam kode agen Anda

1.  **Gunakan variabel lingkungan atau Amazon SageMaker AI** untuk informasi sensitif

1.  **Terapkan prinsip hak istimewa paling sedikit** saat mengonfigurasi izin IAM

1.  **Putar kredensional secara teratur untuk layanan** eksternal

1.  **Log akses audit** untuk memantau aktivitas agen

1.  **Menerapkan penanganan kesalahan yang tepat** untuk kegagalan otentikasi