Skip to content

Commit eb9544a

Browse files
authored
Merge pull request #756 from aws-samples/feature/agentcore-iam-gateway-policy
Feature/agentcore iam gateway policy
2 parents 3581bf3 + 04cdcc8 commit eb9544a

5 files changed

Lines changed: 158 additions & 0 deletions

File tree

apps/java-spring-ai-agents/backoffice/expense/ExpenseService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,13 @@ public Expense getExpense(String expenseReference) {
7777
.items().stream().findFirst()
7878
.orElseThrow(() -> new ResourceNotFoundException("Expense", expenseReference));
7979
}
80+
81+
public Expense deleteExpense(String expenseReference) {
82+
Expense expense = getExpense(expenseReference);
83+
if (expense.getStatus() != Expense.ExpenseStatus.DRAFT) {
84+
throw new InvalidOperationException("Only draft expenses can be deleted");
85+
}
86+
dynamoDbTemplate.delete(expense);
87+
return expense;
88+
}
8089
}

apps/java-spring-ai-agents/backoffice/tools/ExpenseTools.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,10 @@ public Expense submitExpense(
6161
@ToolParam(description = "Expense reference (EXP-XXXXXXXX)") String expenseReference) {
6262
return service.submitExpense(expenseReference);
6363
}
64+
65+
@Tool(description = "Delete a draft expense")
66+
public Expense deleteExpense(
67+
@ToolParam(description = "Expense reference (EXP-XXXXXXXX)") String expenseReference) {
68+
return service.deleteExpense(expenseReference);
69+
}
6470
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/bin/bash
2+
# Deploy Cedar policy to MCP Gateway
3+
# Requires AWS CLI 2.32+
4+
set -e
5+
6+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7+
8+
# Load environment
9+
if [ -f "$SCRIPT_DIR/.env" ]; then
10+
source "$SCRIPT_DIR/.env"
11+
fi
12+
13+
GATEWAY_ARN="arn:aws:bedrock-agentcore:${AWS_REGION}:${ACCOUNT_ID}:gateway/${MCP_GATEWAY_ID}"
14+
POLICY_FILE="${SCRIPT_DIR}/backoffice-policy.cedar"
15+
16+
echo "Deploying Cedar policy..."
17+
echo " Gateway: ${MCP_GATEWAY_ID}"
18+
echo " Policy Engine: ${MCP_POLICY_ENGINE_ID}"
19+
echo ""
20+
21+
# Read and substitute policy
22+
POLICY_STATEMENT=$(sed "s|\${GATEWAY_ARN}|${GATEWAY_ARN}|g" "$POLICY_FILE")
23+
24+
# Delete existing policies and wait for deletion
25+
echo "1. Cleaning up existing policies..."
26+
EXISTING=$(aws bedrock-agentcore-control list-policies \
27+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
28+
--query 'policies[].policyId' --output text 2>/dev/null || true)
29+
30+
for PID in $EXISTING; do
31+
echo " Deleting: $PID"
32+
aws bedrock-agentcore-control delete-policy \
33+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
34+
--policy-id "$PID" > /dev/null
35+
36+
# Wait for deletion to complete
37+
while true; do
38+
STATUS=$(aws bedrock-agentcore-control get-policy \
39+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
40+
--policy-id "$PID" \
41+
--query 'status' --output text 2>/dev/null || echo "DELETED")
42+
43+
if [ "$STATUS" = "DELETED" ] || [ -z "$STATUS" ]; then
44+
break
45+
fi
46+
sleep 2
47+
done
48+
done
49+
50+
# Create new policy
51+
echo ""
52+
echo "2. Creating policy..."
53+
POLICY_ID=$(aws bedrock-agentcore-control create-policy \
54+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
55+
--name "ForbidDangerousOperations" \
56+
--validation-mode "IGNORE_ALL_FINDINGS" \
57+
--definition "{\"cedar\":{\"statement\":$(echo "$POLICY_STATEMENT" | jq -Rs .)}}" \
58+
--query 'policyId' --output text)
59+
60+
echo " Policy ID: $POLICY_ID"
61+
62+
# Wait for ACTIVE
63+
echo ""
64+
echo "3. Waiting for policy to become ACTIVE..."
65+
for i in {1..30}; do
66+
STATUS=$(aws bedrock-agentcore-control get-policy \
67+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
68+
--policy-id "$POLICY_ID" \
69+
--query 'status' --output text)
70+
71+
echo " Status: $STATUS"
72+
73+
if [ "$STATUS" = "ACTIVE" ]; then
74+
echo ""
75+
echo "✅ Policy deployed successfully!"
76+
exit 0
77+
elif [[ "$STATUS" == *"FAILED"* ]]; then
78+
echo ""
79+
echo "❌ Policy deployment failed"
80+
exit 1
81+
fi
82+
sleep 2
83+
done
84+
85+
echo "❌ Timeout waiting for policy"
86+
exit 1
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
# Cleanup Cedar policies from MCP Gateway
3+
set -e
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
7+
if [ -f "$SCRIPT_DIR/.env" ]; then
8+
source "$SCRIPT_DIR/.env"
9+
fi
10+
11+
echo "Cleaning up policies from engine: ${MCP_POLICY_ENGINE_ID}"
12+
echo ""
13+
14+
POLICIES=$(aws bedrock-agentcore-control list-policies \
15+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
16+
--query 'policies[].policyId' --output text 2>/dev/null || true)
17+
18+
if [ -z "$POLICIES" ]; then
19+
echo "No policies found."
20+
exit 0
21+
fi
22+
23+
for PID in $POLICIES; do
24+
echo "Deleting: $PID"
25+
aws bedrock-agentcore-control delete-policy \
26+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
27+
--policy-id "$PID" > /dev/null
28+
29+
echo " Waiting for deletion..."
30+
while true; do
31+
STATUS=$(aws bedrock-agentcore-control get-policy \
32+
--policy-engine-id "${MCP_POLICY_ENGINE_ID}" \
33+
--policy-id "$PID" \
34+
--query 'status' --output text 2>/dev/null || echo "DELETED")
35+
36+
if [ "$STATUS" = "DELETED" ] || [ -z "$STATUS" ]; then
37+
echo " ✅ Deleted"
38+
break
39+
fi
40+
echo " Status: $STATUS"
41+
sleep 2
42+
done
43+
done
44+
45+
echo ""
46+
echo "✅ All policies cleaned up!"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Backoffice MCP Gateway Policy
2+
// Forbid dangerous operations - everything else allowed by default
3+
4+
forbid(
5+
principal,
6+
action in [
7+
AgentCore::Action::"backoffice___cancelTrip",
8+
AgentCore::Action::"backoffice___deleteExpense"
9+
],
10+
resource == AgentCore::Gateway::"${GATEWAY_ARN}"
11+
);

0 commit comments

Comments
 (0)