SearchFIT.ai: Track and grow your brand in AI search
Back to Blog
How-to Guide 21 mins

Identity for AWS Agents: Delegation Without Shared Credentials

A practical AWS design for separating an agent’s workload identity from the user’s authority, with steps for scoped access, delegation and failure handling.

The PADISO Team ·

An agent may run under one technical identity while acting on behalf of many people. That arrangement is useful for operating the software, but it creates a consequential boundary: the agent’s ability to reach a service is not proof that a particular user is allowed to perform a requested business action. If those two questions collapse into one broad credential, a mistake in the prompt, application logic or access policy can affect data and actions beyond the user’s authority.

This guide builds an AWS-oriented reference design around three distinct decisions: which workload is calling, which user or business principal is requesting an action, and which exact operation that principal may perform. The steps are intended for teams designing an agent’s access to existing services. They do not prescribe a particular agent framework or expand into memory retention, tool-gateway implementation or service selection.

Prerequisites

Before designing delegation, identify the agent’s runtime boundary and the services it may call. A short inventory is enough to begin: the agent workload, the user-facing application, the business authorization source, each protected service, and the operations the agent needs. If you cannot name the service that makes the final authorization decision, treat that as a design gap rather than assuming the model will enforce access.

You should also have a way to identify the authenticated user at the application boundary. That identity should be established by your normal sign-in process, not inferred from a name, email address or account number written in a prompt. Decide which stable user or tenant identifier your application will use and how it will be checked against the business system that owns permissions.

Finally, select a narrow first use case. “Read an order’s delivery status” is easier to authorize than “manage orders.” Include a real boundary such as a user, account, tenant, region or record ownership rule. You can then test whether every step preserves that boundary before adding more operations.

Warning: Do not put a long-lived shared user credential in a prompt, agent memory, tool definition or general-purpose configuration. A runtime credential and a user’s business authority solve different problems; carrying one as if it were the other makes access difficult to constrain and audit.

1. Separate workload identity from user authorization

Start by assigning distinct meanings to the identities in the request path. The workload identity identifies the software component making a call. The user identity identifies the person, organization or other business principal whose request initiated it. The authorization decision determines whether that principal may perform a named action on a named resource, under the current conditions.

AWS describes workload identity as identifying the agent workload; it does not replace per-user business authorization. AWS’s overview of agent identities is useful for understanding that distinction. Apply it directly: proving which agent workload is calling a service does not establish that a user may see a particular customer record or submit a particular change.

Keep these concepts separate in both code and data. A request can carry a workload context established by the runtime, a user context established by your application, and an authorization result issued by the component that owns the business rule. Do not allow a model-generated field such as user_id, tenant_id or approved: true to become trusted merely because it appears in a tool call.

The cleanest design places authorization at a boundary that can inspect the real principal and the requested resource. Depending on the system, this may be the business service itself or an authorization component invoked by that service. The agent may help interpret intent and gather parameters, but it should not be the sole authority that grants itself access.

A useful design test is to ask what happens if the model invents a different user identifier, changes a tenant field, repeats an old request, or asks for an action it was never meant to perform. If any of those changes bypass the authorization boundary, the system is relying on the model’s cooperation instead of enforcing access in software.

2. Define the delegation boundary before connecting tools

Write down what the application delegates. Delegation is not simply “the agent can call an API.” It is a constrained permission to attempt a particular class of operation, for a particular principal, against a particular resource, with a defined set of input fields and a defined lifetime. The service still needs to decide whether the operation is allowed at the moment it is requested.

For an initial design, scope access along four dimensions. First, principal: which authenticated user or tenant is represented? Second, action: is this a read, a draft, a submission or a destructive change? Third, resource: which record or account may be affected? Fourth, conditions: what state, amount, status or time limit must hold? Not every system needs a separate policy engine, but every system needs a clear answer to these questions.

A capability such as “read the status of order 483” is narrower than “read all orders for tenant North.” The second may still be valid, but it should be an intentional policy granted to a user with the corresponding role, not a convenience added because it is easier for the agent. Similarly, permission to prepare a change is not automatically permission to submit it.

Avoid passing broad application credentials into an agent process and expecting prompt instructions to keep the process within bounds. Instructions can shape behavior; they are not an access-control boundary. Use the workload’s own identity to establish which software is calling, then have the application or service enforce the user’s business permissions for each operation.

This distinction also clarifies adjacent design questions. What an agent stores between turns is a separate concern from what a user can access; for a deeper treatment of that boundary, see Agent Memory on AWS: Retention, Retrieval and Tenant Boundaries. Likewise, exposing existing APIs as governed tools is a separate implementation topic covered in AgentCore Gateway: Turning Existing APIs into Governed Agent Tools.

3. Establish the request path and trust boundaries

Sketch the route a request takes before implementing the agent’s tools. A sound baseline is: an authenticated user makes a request to the application; the application creates a trusted user context; the agent interprets the request and proposes an operation; a controlled application or service boundary validates that operation; the business service checks authorization and performs the action; and the result returns to the application for display. The model is one participant in this route, not the identity authority.

flowchart TD
    A["Authenticated user"] --> B["Application binds user context"]
    B --> C["Agent proposes operation"]
    C --> D["Boundary validates request"]
    D --> E["Service authorizes user and resource"]
    E --> F["Service performs allowed action"]
    E --> G["Denied or incomplete: stop"]

    accTitle: AWS agent delegation request path
    accDescr: A trusted application binds the user context before the agent proposes an operation. A boundary validates it, and the service makes the authorization decision before either performing the action or stopping it.

The important decision is between validation and execution. The boundary should reject malformed or unexpected inputs, while the business service should evaluate whether the authenticated principal may perform the operation on the resource. If the service cannot make that decision, route the request through a trusted component that can. A denial, missing identity or failed policy lookup must stop the operation; it must not fall through to a broader workload permission.

The diagram deliberately separates “agent proposes operation” from “service performs allowed action.” The proposal can be useful and still be unauthorized. It can also contain an invented identifier, an out-of-range value or an action that is valid in general but invalid for this user. Treat the proposal as untrusted input, even when the model has correctly understood the user’s request.

Keep the trusted user context outside the model’s power to rewrite. The application can bind it to the conversation or request and supply only the necessary representation to the authorization boundary. The model may produce a requested resource identifier, but the application or service must check that identifier against the authenticated principal. A tenant field supplied by the client is not equivalent to a tenant assignment verified by the application.

4. Choose the smallest useful authorization contract

For each operation, define a contract that names the action and the inputs needed to decide it. A read operation might require a user principal, a record identifier and a tenant boundary. A change might additionally require a current record version, a proposed value and a reason. Avoid a generic endpoint that accepts arbitrary method names, resource paths or fields unless the endpoint itself strictly maps those inputs to permitted actions.

A practical contract distinguishes identity facts from request facts. Identity facts are established by trusted application or service logic. Request facts describe what the agent wants to do and must be validated. For example, the authenticated user identifier belongs in trusted context; a requested order number is an input to check; and the permitted operation is a decision, not a model-generated claim.

For read access, filter at the service or data-access boundary using the verified principal and the applicable ownership or tenant rule. Do not retrieve a broad set of records and rely on the model to hide the ones the user should not see. That approach makes authorization dependent on every later prompt, response and memory operation behaving perfectly.

For writes, validate both the requested change and the current state. A request to change a delivery address may be disallowed after shipment, even if the user owns the order. A request to cancel may require a separate permission. Use a narrow operation for each meaningful action rather than a general “update record” call that allows the caller to choose arbitrary fields.

The contract should also define what is returned after denial. A useful response says the operation could not be completed and, where appropriate, what legitimate next step the user can take. Avoid returning sensitive policy details, other users’ information or raw internal errors merely to help the model explain the denial.

5. Implement the reference design in numbered steps

Step 1: Inventory callers, principals and protected operations

List every component that makes or receives an authorization-relevant call. For each one, record its workload identity, the user context it receives, and whether it can read, draft, submit or change data. Include background jobs and retries, not only the interactive agent. A scheduled task without an active user needs its own explicit business authority; it should not quietly impersonate whichever user last interacted with the agent.

Then make an operation inventory with specific verbs. Prefer entries such as read_order_status, prepare_address_change and submit_address_change over a broad “orders tool.” For each operation, name the resource scope and the system that owns the policy. If teams disagree about who decides, settle that before wiring the agent to the operation.

Step 2: Establish the trusted user context at the application boundary

Use the application’s authenticated session or equivalent trusted sign-in result to identify the principal. Map it to the business identifier used by the service, and verify that mapping through an authoritative source. Do not let the agent choose the identity, tenant or role that the application uses for authorization.

Pass only the minimum context necessary to the next boundary. That may be a stable principal identifier and a conversation or request correlation value; it does not need to include every profile attribute. The receiving component must know which parts are trusted and which are user- or model-supplied request parameters.

When a request has no authenticated user, decide explicitly whether the operation is available. Some informational or public functions may be appropriate without a user principal. A private read or consequential change should fail closed if its policy requires an authenticated principal and none is available.

Step 3: Give the workload a distinct, narrow identity

Configure the agent workload to call only the components it needs for its designed role. Keep that workload identity separate from each person’s business permissions. Its purpose is to identify and constrain the software caller; it must not silently stand in for every user who interacts with the agent.

Start with the shortest useful path: the workload can reach an application boundary that validates requests, and that boundary can invoke the business service under a design the service accepts. Do not grant the agent direct access to unrelated data stores or administrative operations simply to avoid implementing a user-aware service boundary.

Review the proposed access from the perspective of a compromised or misbehaving workload. Which operations could it attempt? Which resources could it reach? What would prevent it from changing a user identifier or calling an operation outside the conversational flow? If the answer is “the prompt says not to,” the technical boundary is too broad.

Pro tip: Design the workload’s allowed call surface around named business operations, not a collection of powerful primitives. A smaller surface makes authorization reviews and failure investigation more concrete.

Step 4: Authorize at the business boundary for every operation

Before a protected read or write, evaluate the verified user principal, requested action, target resource and relevant conditions. The business service should not infer permission from the fact that the caller is an agent workload. Make denial the default when required identity or policy information is absent, invalid or unavailable.

For a read, enforce the record-level boundary before returning data to the agent. For a write, check permission immediately before execution and validate that the request still applies to the current record state. A previous successful read is not a standing grant to make a later change; authorization can depend on the latest state and the exact action.

Keep the model’s task distinct from this decision. It can extract a record number from a user’s request or explain a returned result, but the service must verify the record and permission. A confident explanation from the agent does not turn a denied operation into an allowed one.

Step 5: Separate preparation from consequential execution

For an operation that changes business state, consider a two-stage contract: prepare a proposed change, then submit that exact change after the required authorization and any required user confirmation. The preparation result should make the target, fields and intended effect visible to the user or authorized reviewer. Do not treat a general conversational “yes” as approval if the user was not shown what would be executed.

If approval is part of the design, bind it to the exact payload: the principal, operation, resource and proposed values. Set an expiry and reject an approval that is expired, altered or used for a different request. Any change to the payload should require the approval process to run again. This avoids approving one operation and accidentally executing a different one after a retry or model revision.

Approval does not replace authorization. The service still checks that the user may perform the action and that the resource remains in a valid state. Nor should a model claim that the operation succeeded be treated as proof. The application should use the service’s result to determine whether the requested change occurred.

Step 6: Return bounded results and preserve useful evidence

Return only the data needed for the agent to answer the user or continue an authorized workflow. Excess fields create unnecessary exposure and make it easier for private data to leak into later context. Shape success and denial responses so the application can distinguish them without exposing internal policy details to the model.

Record enough information to reconstruct the decision: a correlation identifier, workload identity, verified principal reference, operation, target resource reference, decision, timestamp and service outcome. Avoid recording credentials or unnecessarily copying sensitive payloads into general logs. Define who can inspect these records and how they relate to the application’s existing operational telemetry.

A record of an authorization decision is not itself proof that the business operation completed. Track the decision and the operation outcome separately. For consequential changes, use the authoritative service result to show whether the effect occurred; do not rely on the agent’s natural-language summary as the system of record.

Step 7: Test the boundary with adversarial and ordinary cases

Exercise both legitimate requests and requests designed to cross the boundary. Test a user who may read one record but not another, a tenant identifier that conflicts with the authenticated context, a user who may prepare but not submit a change, and a resource whose state changes between preparation and execution. Confirm that the service—not a prompt convention—rejects each disallowed operation.

Also test incomplete and unavailable states. What happens if the user context is missing, the authorization source times out, the service returns an ambiguous result, or a retry arrives after the first request may have completed? The safe behavior should be explicit. Do not promise exactly-once external effects; design retries so that the application can distinguish a known success, a known denial and an uncertain outcome before attempting a potentially repeated change.

For each test, save the expected decision and the evidence that supports it. A useful acceptance statement is: “A user outside the record’s permitted scope cannot retrieve it even when the agent supplies its identifier.” Another is: “A submission is rejected if the approved payload changes before execution.” These statements are testable without treating model quality as an access-control guarantee.

6. Work through an illustrative scenario

Hypothetical scenario: A retailer wants an agent to answer order-status questions and prepare delivery-address changes. A signed-in customer can see only orders associated with their account. Some address changes may be submitted only while an order is still eligible. The retailer’s order service owns the record and its current state; the application owns the authenticated customer context.

For a status request, the application binds the signed-in customer to the request. The agent extracts an order reference and asks the service for status. The service checks that the customer may access that order before returning a bounded status result. If the order belongs to a different account, the service denies the read even if the agent has correctly formatted the reference and the workload can reach the service.

For an address change, the agent can help gather and normalize the proposed address, but it does not decide eligibility. The service checks the customer’s authority, the order’s current state and the requested fields. If the operation requires confirmation, the application presents the exact target and proposed address and binds the confirmation to that payload. The service checks authorization and state again at submission. If the order has become ineligible, the operation stops.

This design makes a useful distinction between “the user asked for it,” “the agent prepared it,” and “the service accepted and completed it.” Each statement has a separate source of truth. The user request comes from the authenticated interaction, the proposal is produced by the agent and validated, and the final outcome comes from the business service.

An illustrative decision table helps expose the boundary:

RequestTrusted principalService decisionPermitted result
Read order statusCustomer AOrder belongs to Customer AReturn the bounded status
Read another customer’s orderCustomer AOwnership check failsDeny without returning order data
Prepare address changeCustomer AOrder is eligible; customer may prepareReturn a proposal, not a completed change
Submit changed payloadCustomer APayload differs from approved proposalReject and require a new confirmation
Submit after order becomes ineligibleCustomer ACurrent-state check failsDeny and report that no change was made

The table is a design aid, not a claim about a particular retailer or implementation. Its value is that every result follows from a named principal, resource and service decision. A vague outcome such as “the agent is trusted” cannot substitute for any of those fields.

7. Handle failures without widening access

Identity failures should stop at the narrowest point that can identify them. If the application cannot establish the user, do not substitute a default tenant or a privileged service account. If the business authorization check is unavailable, do not bypass it because the workload can still reach the service. Communicate that the action could not be completed and retain a traceable failure reason appropriate for operations.

A stale request deserves particular attention. An agent may prepare an operation, pause while a user reviews it, and then submit after the target record has changed. Re-check the relevant state at execution. If the service cannot determine whether a previous attempt succeeded, avoid blindly repeating a consequential request; retrieve or reconcile the authoritative outcome first where the service supports that workflow.

A mismatch between the authenticated principal and a request field is a security-relevant event, not a harmless formatting issue. Reject it, record the relevant references without exposing secrets, and investigate repeated attempts. Do not “fix” the mismatch by trusting whichever identifier produces a successful response.

Keep user-facing errors useful but bounded. “You cannot access this order” may reveal less than confirming that another account’s record exists. Internal telemetry can distinguish a missing principal, denied resource, invalid state and unavailable policy check without sending that detail back to the model or user.

8. Compare common delegation patterns

A shared, broad application credential is initially simple: one component can call many operations. Its weakness is that the service may see only the application, while the application has little reliable way to apply user-specific rules. A prompt instruction to restrict access does not narrow the credential. This pattern may be appropriate for a genuinely public, non-sensitive operation, but it is a poor default for private records or consequential changes.

A workload identity plus user-aware service authorization separates the technical caller from the business principal. The workload can be recognized as the calling software, while the service checks the authenticated user and the requested resource. This pattern takes more application design and requires consistent propagation of trusted context, but its decisions can be enforced where the business rules and data are evaluated.

A user-context-bearing request without service enforcement appears more specific because each call includes a user identifier. It remains weak if the receiving service accepts that identifier at face value. A client-controlled or model-generated principal is not trustworthy merely because it is present in the request. Use this pattern only when a trusted boundary establishes the context and the service validates it against its own policy.

A prepare-then-submit workflow adds a visible checkpoint for changes. It improves the ability to bind confirmation to an exact operation, but it adds state, expiry and retry handling. It is useful when the impact of a wrong write warrants that friction. It is unnecessary overhead for a low-risk read and should not be represented as a substitute for service authorization.

The right choice depends on the operation, not on a preference for more layers. A simple status read may need a direct, narrowly scoped authorization check. A financial or account-changing action may require preparation, payload-bound confirmation and a fresh state check at submission. In both cases, the workload identity and user authorization remain distinct.

9. Diagnose operational failures by boundary

When a call fails, locate the boundary before changing permissions. A request rejected before reaching the service may indicate malformed input or an absent trusted context. A service denial may indicate that the principal lacks access, the resource is outside scope or current state disallows the operation. A timeout may leave the outcome unknown. These cases require different responses; granting broader access to silence all of them can turn a visible failure into a hidden exposure.

Use correlation identifiers across the application, agent orchestration and service call so operators can follow one request without logging full sensitive content. Include the requested operation and a stable resource reference where appropriate. Keep the decision, execution attempt and resulting state transition distinguishable in the record.

Review repeated denials for both attack signals and product defects. A spike can mean a user is probing records, but it can also mean the application is mapping identities incorrectly or the agent is extracting malformed identifiers. Make telemetry useful enough to tell those possibilities apart, while restricting access to the logs themselves.

When permissions change, test what happens to an already open conversation. Do not assume that a permission granted at sign-in remains valid indefinitely. For sensitive operations, evaluate the current authorization at the point of action. If the business system cannot support that check, document the limitation and choose a workflow that does not imply stronger freshness than the system can provide.

10. Turn the design into an implementation plan

Begin with one read operation and one clearly bounded resource rule. Write its authorization contract, implement the trusted principal path, and test both permitted and denied cases. Add a state-changing operation only after the read path demonstrates that the service—not the agent—enforces user and resource boundaries.

Then review the access surface with the people who own identity, the application and the business service. The review should resolve concrete questions: where the principal is established, which component checks the rule, which fields are trusted, what happens when a check is unavailable, and how an operator can distinguish denial from an uncertain outcome. If those decisions cross team boundaries, a focused cloud platform engineering discussion can help turn them into a maintainable runtime pattern.

Keep this work separate from choosing an agent framework or designing memory. If you first need to distinguish the runtime and orchestration layers, see AgentCore, Bedrock Agents and Strands: Which Layer Does What?. For an adjacent operational prerequisite, the cost drivers and deployment choices are discussed in What an AI Agent Actually Costs on Bedrock AgentCore; cost planning does not change the identity boundary described here.

Printable delegation worksheet

Use this compact worksheet during design review. Fill it in for each operation rather than once for an entire agent. If a field has no clear answer, record it as unresolved and avoid enabling the operation until the responsible team decides how it will be enforced.

Design fieldRecord for this operation
Operation nameA specific verb and business purpose
Workload callerThe runtime component that makes the call
User principal sourceThe trusted sign-in or application boundary
Resource scopeThe record, account or tenant the rule covers
Authorization ownerThe service or component that makes the decision
Required conditionsCurrent state, permitted fields and other relevant rules
Failure behaviorWhat happens for denial, missing identity or unavailable policy
Write confirmationWhether the exact payload requires confirmation and expiry
Outcome evidenceHow success, denial and uncertain completion are distinguished
Negative testA concrete request that must be rejected

A useful review outcome is not simply that every row is filled. The team should be able to explain how an unauthorized request is stopped, how a legitimate request is allowed, and what evidence distinguishes the two. Revisit the worksheet whenever the operation gains a new action, resource scope or caller.

Summary: delegate capability, not authority

Build the boundary around the actual business decision. Identify the agent workload separately from the user, establish the user through a trusted application path, and authorize every protected operation against the principal, action, resource and relevant conditions. The agent can interpret and propose; the service or trusted application boundary must enforce.

Start narrow, keep reads and writes distinct, and make denial the safe result when required identity or policy information is missing. For consequential changes, bind any confirmation to the exact payload and expiry, then recheck authorization and current state at execution. Finally, distinguish an attempted action from a confirmed business result in both user-facing behavior and operational records.

That design gives an AWS agent a defined way to act without turning one shared credential into authority over every user’s data. It also gives engineering teams a testable boundary: workload identity establishes which software is calling, while business authorization decides what that software may do for the authenticated principal.

Want to talk through your situation?

Book a 30-minute call with Kevin (Founder/CEO). No pitch - direct advice on what to do next.

Book a 30-min call