Skip to content

Security: cenetex/agent

Security

SECURITY.md

Security Architecture

This document describes the isolation boundary and security controls for the GitHub Agent infrastructure.

Three-Tier Agent Architecture

The agent system implements a tiered architecture where different agents have different permissions based on their role:

Tier 1: Coding Agent (label: agent)

Permissions:

  • GitHub App token (scoped to installation repositories)
  • OpenRouter API key (for Claude model inference)
  • S3 read-write access (for task artifacts)

Trigger: Any org member labels an issue or PR with agent

Trust Model: Processes untrusted issue bodies with prompt injection boundary (defense in depth)

Risk Profile: Can push code to branches but cannot merge to main

Tier 2: Review Agent (label: review)

Permissions:

  • Same as Tier 1 + Opus model (higher capability)
  • Can label PRs as review-approved, but auto-merge also requires a human GitHub review approval and the hold period

Trigger: Scheduled (every 15 minutes) or manual label

Trust Model: Only reads diffs and posts comments; never trusted with hostile input

Risk Profile: Can recommend merge, but protected paths and final merge eligibility require human review

Tier 3: Diagnostic Agent (label: diagnose)

Permissions:

  • Same as Tier 1 + CloudWatch Logs read-only access (scoped to GitHubAgentStack Lambdas only)
  • Can read Lambda execution logs for debugging

Trigger: Manual label only (org member, human-initiated, never automatic)

Trust Model: Can read deployment logs to diagnose failures and verify task execution

Risk Profile: Logs may contain accidentally leaked secrets (but should not per proper logging practices)

Isolation Boundary

The GitHub Agent executes untrusted code in isolated AWS Fargate tasks within a private network environment. The isolation boundary implements defense in depth with network, compute, and identity controls.

Network Isolation

Private Subnet Execution:

  • Agent tasks run in private subnets by default with no public IP assigned.
  • Outbound internet access goes through a NAT gateway.
  • All inbound access is disabled.
  • Outbound access is controlled through explicit security group rules.
  • Public subnet execution remains available only as an explicit cost-saving CDK context override: -c usePublicSubnets=true.

Explicit Egress Controls:

  • HTTPS (port 443): GitHub API, model inference, and AWS service APIs
  • Package installation and API access must use HTTPS.
  • npm registry (registry.npmjs.org) is intentionally NOT in the worker sandbox egress allow-list. The untrusted model worker cannot run npm install / npm ci to resolve dependencies (DNS resolution fails with EAI_AGAIN). This is a deliberate security policy: dependency installation inside the sandbox could pull arbitrary network-fetched packages into the build.
  • Authoritative test gate: Because the worker sandbox cannot install dependencies, GitHub Actions CI on the pushed PR branch is the sole authoritative test signal. The agent harness treats local-install/lint failure as Unknown (not a verify failure) and relies on CI check-run conclusions to gate the run (see agent/entrypoint.sh verify-outputs stage).

VPC Endpoints:

  • S3 Gateway Endpoint: Private access to artifact storage
  • ECR API/Docker Interface Endpoints: Private container image access
  • CloudWatch Logs Interface Endpoint: Private task logging
  • SSM Interface Endpoint: Private parameter access

Compute Isolation

Fargate Task Model:

  • Each agent invocation runs in an isolated Fargate task
  • Tasks cannot access other running tasks or persistent storage
  • Tasks are ephemeral and destroyed after completion
  • Memory and CPU resources are bounded (2048 MiB, 1024 CPU units)

Task Lifecycle:

  • Task creation is triggered by GitHub webhook events
  • Tasks run with least-privilege IAM roles
  • Tasks are cleaned up automatically after completion or timeout

Identity and Access Controls

IAM Roles:

  • Task execution role: Limited to container lifecycle operations
  • Task role: Scoped to required AWS services (S3 artifacts, SSM parameters)
  • No persistent credentials or broad AWS access

GitHub Integration:

  • GitHub App installation tokens provide scoped repository access
  • Tokens are short-lived and automatically refreshed
  • No persistent GitHub credentials stored in tasks

Security Boundaries

Boundary Control Purpose
Network Private subnets with NAT Avoid direct internet exposure for task ENIs
Egress Security group rules allowing HTTPS only Limit outbound connections
Compute Fargate isolation Prevent task-to-task communication
Storage Ephemeral containers No persistent state between tasks
Identity Scoped IAM roles Limit AWS service access
Repository GitHub App tokens Scope access to specific repositories

Threat Model

Mitigated Threats:

  • ✅ Network-based attacks from internet
  • ✅ Task-to-task communication and data exfiltration
  • ✅ Persistent compromise of infrastructure
  • ✅ Escalation beyond repository scope
  • ✅ Abuse of broad AWS permissions

Residual Risks:

  • ⚠️ Code execution within the repository context (by design)
  • ⚠️ Resource consumption within task limits
  • ⚠️ Outbound network connections within allowed ports

Security Rationale for Diagnostic Agent

The diagnostic agent implements the following security controls to safely access CloudWatch Logs:

IAM Policy Scoping

The diagnostic task role can ONLY read logs from Lambdas that match the pattern /aws/lambda/GitHubAgentStack-*. This is enforced at the IAM policy level (not the application level) and prevents access to:

  • Logs from other services (databases, API gateways, etc.)
  • Logs from other applications or infrastructure
  • Any AWS resources other than CloudWatch Logs read operations

Threat Model

What an attacker with issue-creation access could do:

  • If they achieve org membership, they could label an issue with diagnose
  • The diagnostic agent would then run and could read GitHubAgentStack Lambda logs
  • Those logs contain: webhook payloads, task launch metadata, error messages

What they CANNOT do:

  • Read logs from other services or AWS resources (IAM policy blocks it)
  • Modify or delete logs (read-only permission)
  • Access to API keys or secrets (these are stored in SSM Parameter Store, not in logs)
  • Run arbitrary AWS CLI commands (task role only has specific CloudWatch Logs permissions)

Why this is acceptable:

  • Org members already have AWS console access and could read these logs directly
  • Logs should not contain secrets or credentials by design (these go to SSM)
  • The diagnose label is manual (human-initiated), never automatic
  • The IAM policy is the hard security boundary, not the application logic

Operational Security

Monitoring:

  • CloudWatch logging for all task execution
  • GitHub webhook event logging
  • VPC Flow Logs for network monitoring

Incident Response:

  • Task termination capabilities via ECS APIs
  • Automated cleanup of stale tasks
  • Artifact retention for forensic analysis

Updates and Maintenance:

  • Container images stored in private ECR repository
  • Infrastructure deployed via AWS CDK with version control
  • Parameterized secrets management via AWS SSM

Compliance Notes

This architecture provides baseline isolation suitable for automated code review and implementation tasks on trusted repositories. For handling untrusted or high-risk code, consider additional controls such as:

  • Dedicated VPCs per repository or organization
  • Additional network segmentation
  • Enhanced monitoring and alerting
  • Stricter resource quotas and time limits

There aren't any published security advisories