feat: add Identity CLI commands for managing OAuth authentication and external service access #579
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Secure Integration test | |
| on: | |
| push: | |
| branches: [ main ] | |
| tags: | |
| - 'v*' | |
| pull_request_target: # Changed from pull_request | |
| branches: [ main ] | |
| types: [opened, synchronize, reopened] | |
| permissions: | |
| contents: read | |
| jobs: | |
| authorization-check: | |
| permissions: read-all | |
| runs-on: ubuntu-latest | |
| outputs: | |
| approval-env: ${{ steps.collab-check.outputs.result }} | |
| should-run: ${{ steps.safety-check.outputs.safe }} | |
| steps: | |
| - name: Checkout base branch for safety check | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ github.event.pull_request.base.sha }} | |
| - name: Safety Check - Prevent Workflow Modification Attacks | |
| id: safety-check | |
| uses: actions/github-script@v7 | |
| with: | |
| result-encoding: string | |
| script: | | |
| if (!context.payload.pull_request) { | |
| console.log('Not a pull request, proceeding'); | |
| return 'true'; | |
| } | |
| // Get list of changed files | |
| const { data: files } = await github.rest.pulls.listFiles({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.pull_request.number, | |
| }); | |
| // Check if any workflow files or sensitive files are modified | |
| const dangerousPatterns = [ | |
| /^\.github\/workflows\//, | |
| /^\.github\/actions\//, | |
| /conftest\.py$/, | |
| /pytest\.ini$/, | |
| /^tests\/conftest_mock\.py$/, | |
| ]; | |
| const dangerousFiles = files.filter(file => | |
| dangerousPatterns.some(pattern => pattern.test(file.filename)) | |
| ); | |
| if (dangerousFiles.length > 0) { | |
| console.log('⚠️ SECURITY: PR modifies sensitive files:'); | |
| dangerousFiles.forEach(f => console.log(` - ${f.filename}`)); | |
| console.log('Manual review required before running integration tests'); | |
| return 'false'; | |
| } | |
| console.log('✓ Safety check passed - no sensitive files modified'); | |
| return 'true'; | |
| - name: Collaborator Check | |
| uses: actions/github-script@v7 | |
| id: collab-check | |
| with: | |
| result-encoding: string | |
| script: | | |
| try { | |
| let username; | |
| if (context.payload.pull_request) { | |
| username = context.payload.pull_request.user.login; | |
| } else { | |
| username = context.actor; | |
| console.log(`No pull request context found, checking permissions for actor: ${username}`); | |
| } | |
| const permissionResponse = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| username: username, | |
| }); | |
| const permission = permissionResponse.data.permission; | |
| const hasWriteAccess = ['write', 'admin'].includes(permission); | |
| if (!hasWriteAccess) { | |
| console.log(`User ${username} does not have write access to the repository (permission: ${permission})`); | |
| return "manual-approval" | |
| } else { | |
| console.log(`Verified ${username} has write access. Auto Approving PR Checks.`) | |
| return "auto-approve" | |
| } | |
| } catch (error) { | |
| console.log(`${username} does not have write access. Requiring Manual Approval to run PR Checks.`) | |
| return "manual-approval" | |
| } | |
| check-access-and-checkout: | |
| runs-on: ubuntu-latest | |
| needs: authorization-check | |
| if: needs.authorization-check.outputs.should-run == 'true' | |
| environment: ${{ needs.authorization-check.outputs.approval-env }} | |
| permissions: | |
| id-token: write | |
| pull-requests: read | |
| contents: read | |
| steps: | |
| - name: Configure Credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| role-to-assume: ${{ secrets.AGENTCORE_INTEG_TEST_ROLE }} | |
| aws-region: us-west-2 | |
| mask-aws-account-id: true | |
| - name: Checkout PR head commit | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| repository: ${{ github.event.pull_request.head.repo.full_name }} | |
| persist-credentials: false | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Install dependencies | |
| run: | | |
| pip install -e . | |
| pip install --no-cache-dir pytest click | |
| - name: Run integration tests | |
| env: | |
| AWS_REGION: us-west-2 | |
| AGENTCORE_TEST_ROLE: AgentExecutionRole | |
| id: tests | |
| timeout-minutes: 10 | |
| run: | | |
| pytest tests_integ/cli -s --log-cli-level=INFO | |
| safety-gate: | |
| runs-on: ubuntu-latest | |
| needs: authorization-check | |
| if: needs.authorization-check.outputs.should-run == 'false' | |
| permissions: {} | |
| steps: | |
| - name: Security Block | |
| run: | | |
| echo "🚨 SECURITY BLOCK: This PR modifies sensitive files" | |
| echo "" | |
| echo "The following types of files trigger manual review:" | |
| echo " - Workflow files (.github/workflows/)" | |
| echo " - Action files (.github/actions/)" | |
| echo " - Test setup files (conftest.py, pytest.ini)" | |
| echo "" | |
| echo "⚠️ Integration tests will NOT run automatically" | |
| echo "👀 A maintainer must review the changes and manually trigger tests" | |
| echo "" | |
| echo "This is a security measure to prevent:" | |
| echo " - Workflow modification attacks" | |
| echo " - Secret exfiltration" | |
| echo " - Test manipulation" | |
| exit 1 |