Automationscribe.com
  • Home
  • AI Scribe
  • AI Tools
  • Artificial Intelligence
  • Contact Us
No Result
View All Result
Automation Scribe
  • Home
  • AI Scribe
  • AI Tools
  • Artificial Intelligence
  • Contact Us
No Result
View All Result
Automationscribe.com
No Result
View All Result

Safe AI brokers with Amazon Bedrock AgentCore Identification on Amazon ECS

admin by admin
May 11, 2026
in Artificial Intelligence
0
Safe AI brokers with Amazon Bedrock AgentCore Identification on Amazon ECS
399
SHARES
2.3k
VIEWS
Share on FacebookShare on Twitter


AI brokers in manufacturing require safe entry to exterior companies. Amazon Bedrock AgentCore Identification, accessible as a standalone service, secures how your AI brokers entry exterior companies whether or not they run on compute platforms like Amazon ECS, Amazon EKS, AWS Lambda, or on-premises.

An earlier submit coated AgentCore Identification credential administration for AI brokers. Working brokers on compute environments like ECS raises two questions: construct an application-owned Session Binding endpoint, and easy methods to handle workload entry token lifecycle?

This submit implements Authorization Code Grant (3-legged OAuth) on Amazon ECS with safe session binding and scoped tokens. This submit gives a working implementation with:

  • Safe session binding that stops CSRF and browser-swapping assaults
  • Auth tokens scoped to every consumer session, following least-privilege ideas
  • Separation of considerations between the agent workload and session binding service

Authentication and authorization with OAuth 2.0 and OIDC

This answer makes use of OAuth 2.0 (RFC 6749) and OpenID Join (OIDC). OIDC authenticates customers (who they’re), and OAuth 2.0 authorizes their actions (what they’ll do).

We concentrate on the Authorization Code Grant for user-delegated entry. The consumer authenticates with an id supplier and grants consent. The appliance then exchanges an authorization code for an entry token, which creates an audit path.On this stream, the consumer authenticates with an id supplier and grants consent for the agent to entry particular assets on their behalf. The appliance exchanges the ensuing authorization code for a scoped entry token which Amazon Bedrock AgentCore Identification secures in its token vault. As a result of every token is sure to a selected consumer id with specific consent, the answer maintains an auditable chain from consumer authentication by way of to agent motion.

The Authorization Code Grant is suited to agentic workloads that act on behalf of customers as a result of it gives consumer consent earlier than the agent can act, session binding that verifies the consumer who initiated the authorization request is identical consumer who granted consent, and scoped delegation that limits the agent to solely the permissions the consumer accredited.

Callback URL vs. session binding URL

On this context, the Authorization Code Grant stream makes use of two URLs which might be typically confused:

  • Callback URL: Robotically generated when creating an OAuth shopper in AgentCore Identification. It factors to AgentCore Identification and have to be registered with the Authorization Server because the redirect goal the place the authorization code is shipped after consumer authentication.
  • Session Binding URL: The URL pointing again to a customer-managed service that completes the session binding between the authenticated consumer and the OAuth stream. This endpoint is applied and hosted by the client.

Answer overview

This structure diagram exhibits how AgentCore Identification secures a self-hosted AI agent on Amazon ECS. This walkthrough makes use of Microsoft Entra ID because the id supplier, however different OIDC-compliant suppliers are supported. The entire supply code and conditions for this walkthrough can be found within the accompanying GitHub repository.

The answer deploys two companies on Amazon ECS behind an Software Load Balancer. The Agentic Workload runs the AI agent and handles consumer requests. The Session Binding Service processes OAuth callbacks to hyperlink consumer classes with third-party entry tokens. Each companies use Amazon Bedrock AgentCore Identification to authenticate customers inbound by way of OIDC and authorize outbound actions on their behalf. The numbered annotations within the diagram correspond to the next descriptions.

  1. Inbound authentication and visitors routing: Requests arrive at an Amazon Software Load Balancer (ALB), which authenticates the consumer by way of the ALB’s built-in OIDC authentication stream. Site visitors is encrypted with HTTPS utilizing a certificates from AWS Certificates Supervisor, and an alias A report in an Amazon Route 53 public hosted zone routes visitors to the load balancer. After authenticating the consumer by way of OIDC, the ALB forwards the request to the Amazon ECS cluster. The ALB injects an x-amzn-oidc-data header containing the consumer’s claims in JWT format, with the sub discipline uniquely figuring out the consumer.
  2. Agentic workload: The Agentic Workload exposes a FastAPI server with an /invocations endpoint that accepts a sessionId and message. The FastAPI server passes these to an agent constructed with Strands Brokers. You can even use LangChain or different agent SDKs for the reason that server handles requests independently of the agent framework. The agent calls a big language mannequin (LLM) on Amazon Bedrock, however different mannequin suppliers work, too. The agent shops session state in an Amazon S3 bucket and it makes use of the consumer’s sub declare as a key prefix to isolate classes between customers. The agent additionally has instruments to carry out actions on the consumer’s behalf in GitHub, which requires the consumer’s OAuth entry token.
  3. Outbound authentication with AgentCore Identification: When the agent must act on the consumer’s behalf in a third-party service like GitHub, it requests an OAuth entry token by way of AgentCore Identification. If no legitimate token exists, AgentCore Identification initiates an Authorization Code Grant stream, prompting the consumer to authorize entry.
  4. OAuth callback processing: After the consumer authorizes entry, the Session Binding Service completes the OAuth stream by binding the authorization to the right consumer session by way of AgentCore Identification.
  5. Person interface: The FastAPI server that hosts the agentic workload exposes a /docs endpoint, which renders the OpenAPI specification as an interactive HTML web page. The tip consumer interacts with the agent by way of this web page, which gives a minimal UI for demonstration

Amazon CloudWatch captures logs, and a devoted S3 bucket shops entry logs for each the load balancer and the information bucket. ECS pulls container photos from Amazon ECR. A set of fundamental AWS WAF guidelines is hooked up to the load balancer to offer baseline safety in opposition to widespread internet exploits. An Amazon KMS buyer managed key (CMK) encrypts information, apart from the entry logs bucket, which requires Amazon S3 managed encryption (SSE-S3).

Amazon Bedrock AgentCore Identification: Authorization Code Grant

This walkthrough adapts the normal AgentCore Identification session binding stream for a self-hosted structure utilizing ALB for authentication, a devoted Session Binding Service, and direct API calls as an alternative of the AgentCore SDK and Runtime.

The sequence diagram exhibits how AgentCore Identification’s workload id, workload entry tokens, and OAuth 2.0 credential supplier work collectively to securely present OAuth tokens to the agent on behalf of a consumer. This stream assumes the authenticated consumer has not but approved the agent to entry their assets, that means no legitimate token exists within the AgentCore Identification Token Vault.

  1. An authenticated consumer sends a request to the agentic workload. The agentic workload extracts the consumer ID from the sub declare within the ALB-signed JWT (x-amzn-oidc-data header) to determine the consumer.
  2. The agentic workload calls the GetWorkloadAccessTokenForUserId API, passing the userId and workloadName, to acquire a workload entry token that represents the agent’s id scoped to this consumer.
  3. AgentCore Identification returns the workload entry token to the agentic workload.
  4. The agentic workload calls the GetResourceOauth2Token API, passing the workload entry token, the supplier title of the configured OAuth 2.0 credential supplier, a session binding URL (see callbackUrl parameter), and the required scopes, as an example the learn:consumer scope of GitHub. This requests an OAuth token for the third-party service (on this case, GitHub).
  5. As a result of no legitimate token exists for this consumer, AgentCore Identification creates a sessionURI that tracks the authorization stream state throughout the following requests and responses in the course of the OAuth 2.0 authentication course of.
  6. AgentCore Identification returns an authorization URL and session URI to the workload
  7. The agentic workload returns the authorization URL to the consumer, prompting them to authorize entry.
  8. The consumer clicks the authorization URL and grants the agent permission within the third-party supplier’s consent display screen.
  9. The Authorization Server sends the authorization code to AgentCore Identification.
  10. AgentCore Identification redirects the consumer to the Session Binding URL with the session URI appended, routing them to the Session Binding Service.
  11. The consumer’s browser follows the redirect to the Session Binding Service by way of the Session Binding URL. The ALB injects the JWT within the x-amzn-oidc-data header.
  12. The Session Binding Service calls the CompleteResourceTokenAuth API with the session URI and consumer ID (extracted from the JWT), binding the finished authorization to the right consumer session. On success, it returns a static utility owned HTML web page confirming the authorization was profitable.
  13. AgentCore Identification exchanges the authorization code with the Authorization Server for an OAuth2 entry token.
  14. The Authorization Server returns the OAuth2 entry token.
  15. AgentCore Identification shops the token within the Token Vault.
  16. AgentCore Identification returns success to the Session Binding Service.
  17. The Session Binding Service shows “Authorization full” to the consumer.

On subsequent requests, whether or not the consumer must re-authorize is determined by the credentials the authorization server issued. AgentCore Identification shops each entry tokens and refresh tokens (when accessible) within the Token Vault. When a refresh token is current — as with GitHub when Person-to-server token expiration is enabled — AgentCore Identification routinely makes use of it to acquire a brand new entry token as soon as the unique expires, with out prompting the consumer once more. If no refresh token was issued and the entry token expires, the consumer can be prompted to re-authorize. Notice that tokens will also be revoked on the supplier aspect; in such circumstances, setting forceAuthentication: true forces a contemporary authentication stream.

Session binding:

Session binding protects in opposition to two safety threats:

Cross-Web site Request Forgery (CSRF): An attacker makes an attempt to bind their very own OAuth token to the sufferer’s id, inflicting the sufferer’s agent to unknowingly entry the attacker’s assets, enabling information exfiltration and injection.

Browser Swapping Assault: An attacker methods the sufferer into consenting on their behalf, binding the sufferer’s OAuth token to the attacker’s id, granting the attacker direct entry to the sufferer’s assets.

Session binding prevents each assaults by making certain that the consumer ID on the agent workload matches the consumer ID on the Session Binding Service, with each identities cryptographically verified by way of the authentication chain.

AgentCore Identification additionally helps an non-compulsory customState parameter within the GetResourceOauth2Token API that can be utilized to move a cryptographically random nonce to guard your callback endpoint in opposition to CSRF assaults, as really useful by the OAuth 2.0 specification.

Why we use GetWorkloadAccessTokenForUserId with AWS ALB and Microsoft Entra ID

The really useful API for acquiring a workload entry token is GetWorkloadAccessTokenForJWT. This answer makes use of GetWorkloadAccessTokenForUserId as an alternative.

GetWorkloadAccessTokenForJWT requires a dynamically validatable JWT whose signature may be verified at runtime in opposition to the issuer’s revealed signing keys, and whose aud declare matches your utility. To acquire such a token from Microsoft Entra ID, you have to embrace your Software ID within the scope of the OIDC authorization request, see the AgentCore Microsoft Inbound documentation for particulars.

Nonetheless, that is incompatible with the AWS ALB OIDC stream.

As a part of its OIDC handshake (see ALB OIDC documentation), the ALB sends the entry token to Entra’s UserInfo endpoint to retrieve the authenticated consumer’s claims which is a compulsory step within the ALB’s authentication stream. This UserInfo endpoint is hosted on Microsoft Graph (https://graph.microsoft.com/oidc/userinfo), and it solely accepts tokens scoped to Microsoft Graph. While you embrace your Software ID within the scope, the ensuing entry token has your utility because the viewers, the UserInfo endpoint rejects it with a 401 and the ALB returns a 561.

When you take away your Software ID from the scope, Entra defaults the entry token viewers to Microsoft Graph (00000003-0000-0000-c000-000000000000). The ALB handshake succeeds however the ensuing JWT can’t be dynamically validated by AgentCore. It’s unusable with GetWorkloadAccessTokenForJWT.

This answer: The ALB completes its handshake utilizing the Graph-scoped token. The ALB forwards an ALB-signed JWT within the x-amzn-oidc-data header containing the consumer’s claims from the UserInfo endpoint, together with a sub declare that uniquely identifies the authenticated consumer. We validate this ALB-signed JWT utilizing AWS’s revealed signing keys, extract the sub, and move it to GetWorkloadAccessTokenForUserId.

Implementation

View the whole code GitHub repository.

Acquiring the Workload Entry Token

The server extracts the consumer ID from the JWT’s sub declare and requests a workload entry token from AgentCore Identification. The server then makes use of this token, the session ID, and the message to invoke the agent on behalf of the consumer. Notice that session ID right here refers back to the agent’s dialog session, not the OAuth session URI from the authorization stream.

@router.submit("/invocations")
async def invoke_agent(
    request: InvocationRequest,
    user_id: str = Relies upon(get_current_user),
    settings: Settings = Relies upon(get_settings),
    agent_service: AgentService = Relies upon(get_agent_service),
) -> StreamingResponse:
    """Invoke agent with streaming response."""
    strive:
        agentcore = boto3.shopper("bedrock-agentcore", region_name=settings.identity_aws_region)
        response = agentcore.get_workload_access_token_for_user_id(
            workloadName=settings.workload_identity_name, userId=user_id
        )
        workload_access_token = response["workloadAccessToken"]        
return StreamingResponse(
            content material=agent_service.stream_response(
                user_message=request.user_message,
                session_id=request.session_id,
                user_id=user_id,
                workload_access_token=workload_access_token,
            ),
            media_type="textual content/event-stream",
        )

Requesting the entry token

The server makes use of the require_access_token decorator from AgentCore SDK to retrieve OAuth 2.0 entry token, see Receive OAuth 2.0 entry token. We modify the decorator to just accept the workload entry token as an specific parameter fairly than resolving it internally, giving direct management over token lifecycle administration whereas preserving the SDK’s token retrieval and error-handling logic


def requires_access_token(
    *,
    provider_name: str,
    scopes: listing[str],
    auth_flow: Literal["M2M", "USER_FEDERATION"],
    workload_access_token: str | None = None,
    session_binding_url: str | None = None,
    on_auth_url: Callable[[str], Any] | None = None,
    force_authentication: bool = False,
    token_poller: TokenPoller | None = None,
    custom_state: str | None = None,
    custom_parameters: dict[str, str] | None = None,
    into: str = "access_token",
    area: str | None = None,
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Fetch OAuth2 entry token with specific workload token.

    Args:
        provider_name: The credential supplier title
        scopes: OAuth2 scopes to request
        auth_flow: Authentication stream kind ("M2M" or "USER_FEDERATION")
        workload_access_token: The workload entry token (specific, not from context)
        session_binding_url: Session Binding URL pointing to the customer-managed service that completes the session binding
        on_auth_url: Handler invoked with the authorization URL when consumer authorization is required
        force_authentication: Drive re-authentication
        token_poller: Customized token poller implementation
        custom_state: State for callback verification
        custom_parameters: Extra OAuth parameters
        into: Parameter title to inject the token into
        area: AWS area

    Returns:
        Decorator operate

    """

def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
    shopper = IdentityClient(area)

    @wraps(func)
    async def wrapper(*args: Any, **kwargs: Any) -> Any:
        strive:
            if not workload_access_token:
                increase ValueError("workload_access_token is required")
            token = await shopper.get_token(
                provider_name=provider_name,
                agent_identity_token=workload_access_token,
                scopes=scopes,
                auth_flow=auth_flow,
                callback_url=session_binding_url,
                on_auth_url=on_auth_url,
                force_authentication=force_authentication,
                token_poller=token_poller,
                custom_state=custom_state,
                custom_parameters=custom_parameters,
            )
            kwargs[into] = token
            return await func(*args, **kwargs)
        besides Exception:
            logger.exception("Error in requires_access_token decorator")
            increase

    return wrapper

return decorator

Our instrument class makes use of this decorator to produce the entry token when calling the GitHub API.


class GitHubTools:
    """Instruments for interacting with GitHub utilizing OAuth authentication."""

def _on_auth_url(self, url: str) -> None:
    """Deal with authorization URL by elevating AuthorizationRequiredError.

    This URL have to be offered to the consumer to grant entry.
    """
    increase AuthorizationRequiredError(supplier="GitHub", auth_url=url)

async def _call_github_api(
    self, endpoint: str, scopes: listing[str], params: dict | None = None
) -> Any:
    """Make authenticated GitHub API name.

    Raises:
        ApiError: When API name fails

    """

    @requires_access_token(
        provider_name=self.config.provider_name,
        scopes=scopes,
        auth_flow="USER_FEDERATION",
        workload_access_token=self.config.workload_access_token,
        session_binding_url=self.config.session_binding_url,
        on_auth_url=self._on_auth_url,
        area=self.config.aws_region,
    )
    async def make_request(*, access_token: str) -> Any:
        async with httpx.AsyncClient() as shopper:
            response = await shopper.get(
                f"{self.config.github_api_base}{endpoint}",
                headers={
                    "Authorization": f"Bearer {access_token}",
                    "Settle for": "utility/vnd.github+json",
                    "X-GitHub-Api-Model": "2022-11-28",
                },
                params=params or {},
                timeout=10.0,
            )
            response.raise_for_status()
            return response.json()

    strive:
        return await make_request()

Every instrument within the class makes use of this technique, as proven under:

from strands import instrument
class GitHubTools:
    @instrument
    async def get_github_user(self) -> GitHubUser:
        """Get the authenticated GitHub consumer's profile data.
 
        Use this instrument when the consumer desires to:
        - See their GitHub profile
        - Test who they're authenticated as
        - View their GitHub account particulars
        Returns:
            GitHub consumer profile
        Raises:
            ApiError: When API name fails
        """
        consequence: dict[str, Any] = await self._call_github_api(
            "/consumer", scopes=["read:user"]
        )
        return GitHubUser.model_validate(consequence)

Three key design decisions:

  • Pydantic BaseModel as return sorts: GitHubUser and GitHubProject are BaseModel sub-classes. Strands routinely derives instrument descriptions from their schema and docstrings, giving the LLM structured context about every instrument’s return kind.
  • Kind-consistent error dealing with: When no token exists and AgentCore Identification returns an authorization URL, the on_auth_url callback raises an AuthorizationRequiredError fairly than returning a string — a instrument declaring GitHubUser as its return kind can’t return a URL. The agent’s streaming layer catches the exception and surfaces the URL to the consumer.
  • Scopes per instrument: Every instrument declares solely the OAuth scopes it wants, holding consent aligned with the precept of least privilege.

Finishing the OAuth session binding stream

Subsequent, we take a look at the session binding service. When a consumer authorizes entry in GitHub, GitHub redirects them to {session_binding_url}?session_id={session_id}, the place session_id corresponds to the session URI that AgentCore Identification included within the unique authorization URL. This ties the session binding request to the particular OAuth stream the agent initiated.


@router.get("/session-binding", response_class=HTMLResponse)
async def oauth_session_binding(
    session_id: str = Question(..., description="Session URI from AgentCore Identification"),
    user_id: str = Relies upon(get_current_user),
    settings: Settings = Relies upon(get_settings),
) -> HTMLResponse:
    """Deal with OAuth2 session binding from exterior suppliers.""" 
    shopper = boto3.shopper("bedrock-agentcore", region_name=settings.identity_region)
 
    strive:
        shopper.complete_resource_token_auth(
            sessionUri=session_id,
            userIdentifier={"userId": user_id},
        )

The service extracts the consumer ID from the sub declare within the x-amzn-oidc-data header, making certain constant id throughout the stream. It then calls complete_resource_token_auth with the session URI and consumer ID, which binds the ensuing entry token to the right consumer session.

Cleanup

To keep away from incurring future expenses, delete the assets created by this answer when they’re not wanted. Comply with the instruction for cleansing up the assets.

Conclusion

On this submit, you realized easy methods to safe AI brokers on Amazon ECS utilizing Amazon Bedrock AgentCore Identification. You noticed how inbound authentication verifies consumer id by way of OIDC, how outbound authentication implements OAuth 2.0 with session binding, and the way separating session binding out of your agent workload allows unbiased scaling whereas defending in opposition to assaults. This sample works throughout totally different compute platforms, whether or not you run brokers on ECS, EKS, Lambda, or outdoors AWS solely. It additionally extends past GitHub to different OAuth 2.0-enabled companies like Jira, Salesforce, or Google Calendar. Subsequent steps:

  1. Evaluate the whole code in GitHub to see the implementation
  2. Adapt the sample to your OAuth supplier, substitute GitHub along with your service
  3. Discover extra patterns within the AgentCore Identification Samples repository
  4. Learn the submit on AgentCore Runtime for managed agent internet hosting
  5. Dive into the AgentCore Identification documentation

Concerning the authors

Julian Grüber is a Knowledge Science Guide at Amazon Internet Companies. He companions with strategic clients to scale GenAI options that unlock enterprise worth, working at each the use case and enterprise structure stage. Drawing on his background in utilized arithmetic, machine studying, enterprise, and cloud infrastructure, Julian bridges technical depth with enterprise outcomes to deal with complicated AI/ML challenges

Tobias works as Safety Guide at Amazon Internet Companies as a Safety Engineer. Tobias combines hands-on answer constructing with strategic advisory to assist enterprise customersaccelerate their cloud transformation and obtain their enterprise aims. He focuses on partnering with strategic clients to design and scale GenAI options, working at each the use-case and enterprise-architecture stage.

Satveer Khurpa is a Sr. WW Specialist Options Architect, Amazon Bedrock AgentCore at Amazon Internet Companies, specializing in agentic AI safety with a concentrate on AgentCore Identification and Safety. On this function, he makes use of his experience in cloud-based architectures to assist purchasers design and deploy safe agentic AI techniques throughout various industries. Satveer applies his deep understanding of agentic AI patterns, id and entry administration, and defense-in-depth safety ideas to architect scalable, safe, and accountable agent-based purposes, enabling organizations to unlock new enterprise alternatives whereas sustaining strong safety postures for autonomous AI workloads.

Tags: AgentCoreAgentsAmazonBedrockECSIdentitysecure
Previous Post

Batch or Stream? The Everlasting Knowledge Processing Dilemma

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Popular News

  • Greatest practices for Amazon SageMaker HyperPod activity governance

    Greatest practices for Amazon SageMaker HyperPod activity governance

    405 shares
    Share 162 Tweet 101
  • How Cursor Really Indexes Your Codebase

    404 shares
    Share 162 Tweet 101
  • Construct a serverless audio summarization resolution with Amazon Bedrock and Whisper

    403 shares
    Share 161 Tweet 101
  • Speed up edge AI improvement with SiMa.ai Edgematic with a seamless AWS integration

    403 shares
    Share 161 Tweet 101
  • Democratizing AI: How Thomson Reuters Open Area helps no-code AI for each skilled with Amazon Bedrock

    403 shares
    Share 161 Tweet 101

About Us

Automation Scribe is your go-to site for easy-to-understand Artificial Intelligence (AI) articles. Discover insights on AI tools, AI Scribe, and more. Stay updated with the latest advancements in AI technology. Dive into the world of automation with simplified explanations and informative content. Visit us today!

Category

  • AI Scribe
  • AI Tools
  • Artificial Intelligence

Recent Posts

  • Safe AI brokers with Amazon Bedrock AgentCore Identification on Amazon ECS
  • Batch or Stream? The Everlasting Knowledge Processing Dilemma
  • Introducing OS Stage Actions in Amazon Bedrock AgentCore Browser
  • Home
  • Contact Us
  • Disclaimer
  • Privacy Policy
  • Terms & Conditions

© 2024 automationscribe.com. All rights reserved.

No Result
View All Result
  • Home
  • AI Scribe
  • AI Tools
  • Artificial Intelligence
  • Contact Us

© 2024 automationscribe.com. All rights reserved.