Skip to content
Effloow
← Back to Articles
ARTICLES ·2026-06-10 ·BY EFFLOOW CONTENT FACTORY

GitHub Agent Tasks REST API: Safe Automation Launcher PoC

Build a dry-run launcher for GitHub Agent Tasks REST API with payload validation, audit logs, and governance checks.
github-copilot agent-tasks rest-api developer-tools automation governance ai-agents
SHARE
GitHub Agent Tasks REST API: Safe Automation Launcher PoC

GitHub's Agent tasks REST API gives platform teams a new automation surface: start and track Copilot cloud agent tasks from an internal tool instead of asking every developer to click through GitHub. That sounds like a developer portal feature, but it is also a governance problem. A bad launcher can turn a vague prompt into a background coding task against the wrong repository, branch, model, or pull request policy.

This article builds the safer first version: a dry-run launcher that validates the request, records the decision, and refuses to start a live task. Effloow Lab ran a bounded OpenAI API check against a source-derived launcher design and saved the public lab note at /lab-runs/github-agent-tasks-rest-api-automation-poc-2026. The check produced useful guardrails for preflight checks, payload validation, audit fields, and create_pull_request=false defaults. It did not call GitHub, start a Copilot task, create a branch, or measure task success.

Primary sources for this guide include GitHub's June 4, 2026 changelog, the Agent tasks REST API docs, the Copilot cloud agent overview, the Copilot cloud agent session docs, GitHub's repository custom instructions docs, GitHub's MCP documentation, and the Copilot cloud agent secrets and variables docs.

If you are building the broader governance layer around this launcher, pair it with Effloow's guide to auditing Copilot cloud agent configuration and the earlier Copilot SDK governed runtime PoC. This article focuses only on the task-launch surface.

What You'll Build

You will build a local request validator that behaves like the first screen of an internal developer portal. A developer enters an owner, repository, prompt, base branch, optional head branch, optional model, and a pull-request preference. The tool validates the shape, prints the exact API request that would be sent, writes an audit record, and exits without contacting GitHub.

The documented start endpoint is:

POST /agents/repos/{owner}/{repo}/tasks

GitHub's REST docs for API version 2026-03-10 list prompt as required and model, create_pull_request, base_ref, and head_ref as body parameters. The docs also show repository-scoped list and get endpoints for tracking tasks, plus known states such as queued, in_progress, completed, failed, idle, waiting_for_user, timed_out, and cancelled.

The PoC outcome is deliberately modest:

  • a validated JSON payload;
  • a redacted audit record;
  • a policy decision that keeps create_pull_request false by default;
  • a clear statement that live response behavior is [DATA NOT AVAILABLE] until you run the endpoint with an eligible account and safe repository.

Prerequisites

Use Node.js 20 or newer for the local validator. You do not need a GitHub token for the dry run below because the script must not submit a request.

mkdir github-agent-task-launcher-poc
cd github-agent-task-launcher-poc
npm init -y

Expected output:

package.json created

For a future live implementation, GitHub's docs require current account, plan, repository, and token checks. The June 4 changelog says Agent tasks REST API access is available for Copilot Pro, Pro+, and Max users. The REST endpoint page also says the start endpoint is only available to users with a Copilot Business or Copilot Enterprise subscription. Because those statements are different surfaces of fast-moving documentation, a production launcher should verify eligibility against the actual account before enabling live starts. This article does not resolve plan-specific eligibility beyond the cited sources.

Step 1: Create the Request Schema

Create validate-agent-task.mjs:

import { createHash } from "node:crypto";
import { writeFileSync } from "node:fs";

const allowedModels = new Set([
  "claude-sonnet-4.6",
  "claude-opus-4.6",
  "gpt-5.2-codex",
  "gpt-5.3-codex",
  "gpt-5.4",
  "claude-sonnet-4.5",
  "claude-opus-4.5"
]);

const input = {
  owner: "octo-org",
  repo: "internal-portal",
  prompt: "Inspect the onboarding route and propose a small refactor plan.",
  base_ref: "main",
  head_ref: "",
  model: "gpt-5.3-codex",
  create_pull_request: false
};

function requireSlug(value, label) {
  if (!/^[A-Za-z0-9_.-]+$/.test(value)) {
    throw new Error(`${label} must be a GitHub-style owner/repo/ref token`);
  }
}

function validate(input) {
  requireSlug(input.owner, "owner");
  requireSlug(input.repo, "repo");
  requireSlug(input.base_ref, "base_ref");

  if (input.head_ref) requireSlug(input.head_ref, "head_ref");
  if (!input.prompt || input.prompt.trim().length < 20) {
    throw new Error("prompt must be specific enough to review");
  }
  if (input.prompt.includes("token") || input.prompt.includes("password")) {
    throw new Error("prompt appears to include credential-like text");
  }
  if (input.model && !allowedModels.has(input.model)) {
    throw new Error("model is not in the documented allowlist for this validator");
  }
  if (input.create_pull_request !== false) {
    throw new Error("dry-run launcher requires create_pull_request=false");
  }
}

validate(input);

const payload = {
  prompt: input.prompt,
  model: input.model,
  create_pull_request: false,
  base_ref: input.base_ref
};

if (input.head_ref) payload.head_ref = input.head_ref;

const endpoint = `https://api.github.com/agents/repos/${input.owner}/${input.repo}/tasks`;
const promptHash = createHash("sha256").update(input.prompt).digest("hex");

const audit = {
  timestamp: new Date().toISOString(),
  dry_run: true,
  api_version: "2026-03-10",
  method: "POST",
  endpoint,
  owner: input.owner,
  repo: input.repo,
  token_value_stored: false,
  token_type_required: "fine-grained PAT or GitHub App user access token",
  installation_token_supported: false,
  required_repository_permission: "Agent tasks: read/write",
  prompt_sha256: promptHash,
  model: input.model || null,
  create_pull_request: false,
  base_ref: input.base_ref,
  head_ref: input.head_ref || null,
  live_github_request_sent: false,
  live_response: "[DATA NOT AVAILABLE]"
};

writeFileSync("agent-task-dry-run-audit.json", JSON.stringify(audit, null, 2) + "\n");
console.log(JSON.stringify({ endpoint, payload, audit_file: "agent-task-dry-run-audit.json" }, null, 2));

Run it:

node validate-agent-task.mjs

Expected output:

{
  "endpoint": "https://api.github.com/agents/repos/octo-org/internal-portal/tasks",
  "payload": {
    "prompt": "Inspect the onboarding route and propose a small refactor plan.",
    "model": "gpt-5.3-codex",
    "create_pull_request": false,
    "base_ref": "main"
  },
  "audit_file": "agent-task-dry-run-audit.json"
}

That output is not a GitHub response. It is a validated request preview. The difference is the point of the PoC.

Step 2: Add Preflight Checks Before Any Live Mode

Before a launcher can send a real POST, it needs preflight checks that are separate from payload formatting. GitHub's docs say fine-grained GitHub App user access tokens and fine-grained personal access tokens can be used for Agent task endpoints, while GitHub App installation access tokens are not supported for the documented repository endpoints. The start endpoint requires Agent tasks repository permission with read and write access.

Add these checks to your portal before showing a launch button:

1. Confirm the user intentionally selected the repository.
2. Confirm the token type is supported.
3. Confirm Agent tasks repository permission is read/write.
4. Confirm account eligibility for the selected plan and organization policy.
5. Confirm the repository has not disabled Copilot cloud agent.
6. Confirm the base branch and optional head branch are correct.
7. Confirm repository instructions, path-specific instructions, and AGENTS.md are expected.
8. Confirm MCP secrets and variables use the COPILOT_MCP_ prefix when MCP servers need them.
9. Confirm the user saw that a live task can create agent changes in GitHub's environment.

The current PoC can store unresolved checks as "unverified" rather than pretending they passed. For example:

{
  "account_eligibility": "unverified",
  "organization_policy": "unverified",
  "repository_agent_enabled": "unverified"
}

That is not weak documentation. It is honest automation design. A buyer evaluating Effloow-style technical content should care that the article distinguishes source-backed facts from account-specific runtime behavior.

Step 3: Keep create_pull_request False by Default

GitHub's Agent tasks API includes create_pull_request, and the docs list the default as false. Keep that default. Starting with a branch-based task lets a reviewer inspect the agent's direction before the workflow becomes a pull request workflow.

Set or force create_pull_request=false when:

  • the request is a preview or dry run;
  • the prompt has not been reviewed;
  • the base branch is not confirmed;
  • the selected model is not verified for the account;
  • the task is exploratory research rather than a ready implementation;
  • repository owners require human approval before any agent-created PR.

Use true only after an explicit approval step. Even then, the audit record should capture who approved it, what prompt was submitted, which repository was targeted, which base/head refs were selected, and whether repository instructions were in scope.

Step 4: Track States Without Inventing Outcomes

Once a future live launcher starts a task, tracking should use the documented task states instead of vague strings such as "running" or "done." A polling loop can normalize the response:

const terminalStates = new Set(["completed", "failed", "timed_out", "cancelled"]);
const activeStates = new Set(["queued", "in_progress", "idle", "waiting_for_user"]);

function classifyTaskState(state) {
  if (terminalStates.has(state)) return "terminal";
  if (activeStates.has(state)) return "active";
  return "unknown";
}

For this article, live task IDs, response bodies, usage limits, and success rates are [DATA NOT AVAILABLE]. The GitHub docs show example responses, but example JSON is not proof that your account, repository, policy, and model selection will behave the same way.

Step 5: Design the Audit Log for Review

The audit log is the product surface buyers will ask for. It should be useful to a platform team, security reviewer, and engineering manager without storing secrets.

Record:

  • actor and timestamp;
  • target owner and repository;
  • intended endpoint and API version;
  • token type category, never the token value;
  • permission preflight result;
  • account eligibility result;
  • prompt hash and a redacted prompt summary;
  • selected model, if any;
  • base_ref and head_ref;
  • create_pull_request value;
  • whether a live GitHub request was sent;
  • task ID and state only after live mode exists;
  • approval decision and approver for real launches.

Do not store:

  • bearer tokens;
  • MCP secrets;
  • raw customer data in prompts;
  • full repository contents;
  • private issue bodies unless your policy explicitly permits it.

Verify It Works

For the dry run, verification is local:

test -f agent-task-dry-run-audit.json
node -e "const a=require('./agent-task-dry-run-audit.json'); if (a.live_github_request_sent !== false) process.exit(1); console.log(a.live_response)"

Expected output:

[DATA NOT AVAILABLE]

That output confirms the script did not pretend to have a GitHub response. If your validator prints a task ID during dry-run mode, treat it as a bug unless you actually sent a live request in a safe repository and saved the evidence.

Troubleshooting FAQ

Q: Can this safely run against production repositories?

The dry-run validator can be used with production repository names because it does not call GitHub. A live launcher should start with a non-critical repository, explicit approval, narrow prompts, and repository-owner review.

Q: Which token should the launcher use?

For the documented repository endpoints, use the supported token types in GitHub's Agent tasks REST API docs and require the Agent tasks repository permission. The exact token issuance flow depends on your GitHub organization and app architecture, so live implementation details are account-specific.

Q: Does this replace GitHub's own UI?

No. It wraps the API with a control plane: approvals, validation, audit logs, and developer-portal workflow. Teams that only need occasional manual tasks may not need a custom launcher.

Q: Can the API pick any model?

No. The REST docs list currently supported values, and GitHub says allowed models can change over time and depend on plan and organization policy. Validate the model field at runtime instead of freezing assumptions forever.

Q: Did Effloow start a real Copilot cloud agent task?

No. Effloow Lab ran an OpenAI API check on the dry-run launcher design and recorded the limitations. No GitHub token was used and no Agent tasks API request was sent.

Buyer Readiness Checklist

Use the Agent tasks REST API when your buyer needs controlled delegation from an internal portal, recurring engineering queues, or platform-approved task launch flows. Do not lead with automation until the control plane is ready.

Bottom Line

A safe Agent tasks REST API PoC starts as a dry-run launcher, not a background-code factory. Validate the account, token, repository, branch, model, prompt, and PR policy before allowing a live POST.

Minimum readiness:

  • source-verified endpoint and API version;
  • explicit plan and policy eligibility check;
  • token-type and permission check;
  • repository and branch confirmation;
  • prompt review workflow;
  • create_pull_request=false default;
  • audit logs that do not store secrets;
  • clear handling for waiting_for_user, timed_out, failed, and cancelled;
  • documented escalation path when a task needs human review.

That is the article-to-product opportunity: turn a new agent endpoint into a governable launcher that engineering teams can inspect before they trust it.

Need evidence-led content
for your tool?

Send one product URL or technical claim. We will map the right path for an article, PoC write-up, or tool package.

Send a brief →

More in Articles

Stay in the loop.

One dispatch every Friday. New articles, tool releases, and a short note from the editor.

Get weekly AI tool reviews & automation tips

Join our newsletter. No spam, unsubscribe anytime.