Skip to content

Private Context in Public Agent Workflows ​

How can an agent use private planning or issue-tracking context while working on a public repository without publishing information beyond its authorized audience?

The problem ​

A public repository can have legitimate dependencies on private information: an internal issue tracker, a business roadmap, an unreleased requirement or a restricted design discussion. Giving an agent access may improve its work. That read permission does not also authorize public disclosure.

The boundary applies to the agent's whole invocation. Protected input can appear in runtime-emitted thinking, assistant text, tool summaries, lifecycle script output, validation feedback, artifacts, traces and forge writes. A private artifact store does not make a public review body safe. A quiet console does not protect a transcript uploaded as a public-repository artifact.

This problem is independent of the tracker product, forge or organization. It also arises without an attack: quoting relevant context is a natural part of explaining a review. Prompt injection creates an additional path by asking an agent to repeat or summarize protected material.

Existing design and gaps ​

ADR 0021 chooses access control for full-fidelity transcripts rather than relying on heuristic sanitization. ADR 0021's owner-scoped storage has not been implemented for any repository. By default, the GitHub action and GitLab CI template upload the whole run output, including transcripts, as forge-native artifacts. On GitHub, any signed-in user can download artifacts from a public repository; private-repository artifacts are available to repository readers, not just owners. The GitLab template sets no artifacts:access restriction. GitLab's artifacts:access defaults to all, so artifacts in public pipelines are downloadable by anyone, including anonymous users. #6734 tracks alternative artifact storage, including disabling forge-native uploads.

ADR 0021 also specified opt-in suppression of the JSONL transcript artifact, declared in agent configuration for protected external sources. That opt-out was never built. ADR 0161 replaces it with a repository-level artifacts setting in config.yaml, implemented in the GitHub action and the GitLab CI template. The setting picks one level for each run: all uploads the whole run output, metadata uploads only run-level metrics and telemetry with conversation content removed, and none uploads nothing. A by_source entry can set a stricter level for runs started from one source, such as a Jira issue. The run artifacts guide describes how to use it.

The setting narrows one publication path, and it has limits. The default is all, so the artifact holds the whole run output until the repository owner sets a stricter level. by_source looks only at where the run started, not at every private system the agent can read on that run. metadata still publishes identifiers such as the work item id and the branch name. The withheld files exist only on the runner; there is no private store for them. Neither decision covers console output, reviews or other forge writes, and remote trace export is unchanged at every level.

The harness schema does declare a security.trace.enabled field. Its name can suggest a switch for traces, but it is not the control ADR 0021 describes. The schema documents it as trace ID generation for correlating security findings. It does not select protected sources, and it does not suppress transcripts, telemetry files or artifact uploads.

The existing private-repositories guide provides operator guidance: AGENTS.md disclosure rules, per-agent risk recommendations, manual steps for checking agent output and the harness SecretRedactor. Those controls depend on agents following the instructions and on patterns the scanner can recognize. The guide rates triage, coder and review as low risk because their output stays in the source repository. It also treats agent output in a public repository as harmless because the repository content is already public. Neither assumption holds when a public repository's agents read private sources outside that repository.

The scribe agent already requires a public_safe classification for each topic and new issue, with a single-word public_safe_category for rejected content. Its post-script checks that flag for topics and new issues before repository writes. For items marked unsafe, it skips the write and logs the category instead of the title or body. This constrains scribe's forge writes and rejection-log text, but trusts the model's own classification. It does not independently validate the publication safety of derived content marked safe, or protect artifacts, transcripts or the live console thinking stream. It is an existing release gate with limited coverage, not a general confidentiality guarantee.

Live runtime-event rendering (PR #3186) streams model thinking and assistant text to the job console. On a public repository, protected input quoted in that output reaches public job logs even if artifact uploads are suppressed.

ADR 0050 decides how telemetry is generated. Every run writes a local span file to the output directory, and the ADR notes that this directory is uploaded as GitHub Actions artifacts alongside transcripts. Export to a remote OTLP endpoint is opt-in. For content capture, the ADR makes the organization responsible for the access controls of its backend. The ADR does not address who can read console output or public reviews.

This document draws its own conclusion from those points: exporting to a private endpoint does not change the audience of the local span file, console output or public reviews. With content capture enabled, captured content is also written to the local span file, so it reaches the same forge artifact at the default all level. The metadata level removes captured content from the uploaded copy of that file, and none uploads no artifact.

#2513 records the direction to use private GitHub repositories as the standard for private Jira refinement. It chooses documentation warnings as the immediate step and a harness-level runtime check that warns or blocks Jira integration in a public repository as the follow-up. This records the intended guard, rather than establishing that runtime enforcement is available. One narrower warning now exists: a run started from an external tracker warns when it uploads its full transcript, the configuration makes no artifacts choice for that source and the repository is not known to be private. It covers the artifact only and does not block the run.

#1189 identifies that retro issues about a private source repository can expose private content in a public destination. It notes that restricting which repositories retro may target (#978) does not address the content of the filed issue.

These two issues establish parts of the problem. Neither a documentation warning nor a restriction on destinations shows that derived content is safe to publish.

Boundaries to account for ​

  • Observability: stdout/stderr, CI annotations, summaries, raw streams, transcripts, local telemetry, remote traces, debug and security records.
  • Public effects: reviews, inline comments, issues, PR descriptions, generated code and tests, filenames, commits and other agent-driven writes.
  • Continuation: retro, fix, debugging, resumption and chained agents that consume prior private evidence.
  • Policy authority: who may authorize disclosure or impose a blocking decision on the public project, and which configuration is trusted.

Credential isolation and scanning remain necessary. They do not classify ordinary private prose or determine whether a derived business conclusion may be published. Moving a runner onto private infrastructure also does not change the audience of logs published by a public-repository workflow.

Input access and publication permission are separate controls. Protected context can enter through deterministic prefetch code as well as an agent's retrieval tools. Restricting tool access alone does not protect prefetched content; suppressing output does not reduce what the agent can read.

Options and trade-offs ​

Refuse or warn on protected sources for public-repository installs ​

Check the repository's visibility and configured sources before allowing an agent to read protected context. Refuse that combination or warn the operator, starting with the runtime validation planned in #2513 for Jira integrations. Apply the check during setup and before execution so later configuration or visibility changes also receive validation.

Refusal can prevent known unsafe configurations without having to sanitize all downstream output. It can also exclude useful workflows that separate private processing from approved public output. A warning preserves operator choice but does not prevent disclosure if the operator proceeds. Both choices need trusted source classification, coverage of custom integrations and a policy for unknown sensitivity. Repository visibility alone does not identify all private inputs or public destinations.

Keep protected processing in a private execution environment ​

Run the confidential stage in an access-controlled worker or control repository. Publish only approved material to the public project.

This narrows exposure and can retain useful private evidence. It requires cross-repository authorization, dispatch, artifact retrieval and status correlation. The private-repository direction above does not establish that fullsend provides this cross-repository publishing arrangement.

Restrict the public job's inputs to approved public material ​

Provide an explicitly approved public projection of requirements. Keep private tracker access out of that invocation.

This gives the public agent information it can explain and cite. Someone must maintain the projection, prevent stale requirements and decide what may be released. It may omit context needed for private policy decisions.

Making the entire source public is a separate disclosure decision: existing descriptions, comments, attachments and future updates would all need a publication policy. It is not equivalent to approving a limited projection.

Mediate access to protected context ​

ADR 0141 already chooses deterministic, filtered staging of forge entity content for issue and change-proposal runs. It applies ADR 0133, which separates actor authorization, data admission and platform authority. ADR 0133 describes a target contract and states that the complete boundary is not yet enforced on every model-bound path. Direct model-initiated source-system calls remain outside ADR 0133's guarantee. Neither decision authorizes publication of admitted private content; this option builds on that admission boundary rather than replacing it.

For other protected sources, have trusted pipeline code select the context before execution, or expose a restricted retrieval interface whose source permissions and network controls prevent broader access. Neither approach requires giving the agent unrestricted access to an entire tracker or document store.

Context needs vary by task. A change may need one work item's approved fields, while duplicate detection or retrospective analysis may need a broader corpus. For sources outside the decided staging scope, compare bounded prefetch with scoped retrieval for task effectiveness and disclosure risk. The choice depends on the task and disclosure policy.

Source-specific controls may operate at issue, comment or field granularity. Their visibility settings must be interpreted explicitly: a source's "public" audience may still require authentication, and permission to read does not itself authorize publication. Classification needs to travel with selected context and derived work items. These controls reduce exposure but do not make all information received by the agent safe for public output.

Allow protected context with controlled output destinations ​

Route full evidence to private storage and internal trace endpoints. Possible artifact destinations include a private S3 bucket or a private OCI registry accessed with ORAS. Restrict public logs to approved operational metadata and constrain public writes.

This can preserve existing workflow placement and detailed debugging. It requires enforcement across every lifecycle stage and publication path, including custom scripts and failures. Public fallback when private storage fails would defeat the boundary. Trusted policy must apply before private reads and cannot be weakened by the untrusted PR or agent.

A narrower control limits what the artifact publishes for protected runs. ADR 0161 decides this form: the runner keeps the full output for its own steps and uploads a filtered copy, or none. It adds no private store, so retro analysis, resumption and follow-up workflows lose the withheld evidence. Keeping an authorized private copy is a separate choice, which #6734 tracks. An artifact level does not prevent disclosure through logs, public comments or generated code. It is a partial mitigation, not a confidential mode.

GitLab's artifacts:access setting can restrict artifact downloads through the UI and API. This is a partial, forge-specific mitigation: it does not prevent forwarding artifacts to downstream pipelines or access through runner APIs using job tokens. Job-token access requires separate project CI/CD visibility controls. Artifact access restrictions also leave logs, public comments and generated code outside their protection.

Separate private planning and public contribution loops ​

Keep private planning stages and their work items within a private execution and tracking environment. An authorized release step produces an approved public work item. Public contribution agents work only from public material; a separate private process can ingest public progress and update private tracking without publishing the private linkage.

The release step could be implemented by a person, trusted pipeline code or a constrained agent. A handoff limited to creating public issues need not also have permission to push code or merge changes. This is a separation of trust domains, not just a private runner targeting a public repository, and does not require choosing new agent roles here.

This limits which stages handle private context, but the release step remains a disclosure boundary requiring validation or approval. Keeping work items current adds coordination cost. Public agents may miss relevant private dependencies until approved information is relayed, so the effectiveness of the handoff also needs evaluation.

Separate public technical review from private policy evaluation ​

A public review cites public evidence. A private evaluator checks protected planning constraints and retains its rationale privately. An authorized publisher releases only an approved result or sends it for human review.

This avoids asking one free-form public explanation to carry a private rationale safely. It introduces result binding, freshness, merge-policy and operator responsibilities. It does not eliminate information disclosure: a public hold can reveal a private decision, and repeated proposals may reveal more about the hidden policy.

These options can be combined. A project might use public requirements for technical review, private execution for planning checks and private evidence storage for the latter. The choice depends on the permitted disclosures and the project's governance.

Indirect disclosure through derived work ​

Removing explicit private identifiers does not necessarily remove the information they reveal. For a hypothetical example, a private requirement could lead to a distinctive compatibility exception in an intermediate work item, then a matching code branch or test in a public PR. An observer familiar with that constraint could infer the private context without seeing its name.

This can happen across several planning and coding stages without a direct quotation or a credential leak. Public-release review must therefore consider derived requirements and observable behavior as well as text. Source labels, prompt instructions and pattern-based redaction alone do not establish that the released result cannot reveal protected information.

Example: a private roadmap affects a public PR ​

Suppose a proposal conflicts with a confidential roadmap. An unrestricted review might explain the conflict by quoting a private milestone or business rationale. A code agent could copy private acceptance criteria into a public PR description. These are hypothetical examples, independent of any product or organization.

With a separate private policy evaluation, the private evaluator's evidence and explanation remain internal. If the project explicitly permits it, a publisher could issue the fixed public message "Maintainer review required before merge."

A required check could enforce that hold, but only with trusted results tied to the repository, current PR head and applicable policy. Missing or stale results must not authorize merge. The public decision bit is itself a release of information. If even that signal is unacceptable, a uniform maintainer gate may be more appropriate.

Knowing a downstream contributor's private priorities is also different from having authority to veto an upstream contribution. Private planning policy should not be misrepresented as a publicly demonstrated code defect or fed into an automated fix loop as though it were an actionable public finding.

Evidence needed before calling a mode confidential ​

Use synthetic protected markers rather than real private records. Exercise runtime text, commands and tool responses, lifecycle scripts, validation, errors, retries, timeouts, cancellations and storage failures. Inspect actual public logs, artifacts, annotations, summaries and forge writes for disclosure.

Verify that evidence remains accessible to authorized private consumers, that unauthorized readers are denied, and that subsequent agents preserve the same boundary. Test bypass attempts through direct APIs, shell tools, custom scripts and generated patches. Credential scanning or a second LLM's approval alone cannot demonstrate the required confidentiality property.

Relationship to other problem areas ​

  • Security threat model: indirect disclosure and prompt injection can produce the same public leak.
  • Operational observability: preserving useful debugging evidence while controlling its audience.
  • Agent infrastructure: execution placement and infrastructure ownership do not alone determine output visibility.
  • Downstream/Upstream: authority to reconcile private business priorities with the public project's direction.
  • Cross-run memory: lessons and evidence that a run carries forward can also carry private context to a later run with a wider audience.

Open questions ​

  • How should protected sources and run classification be declared and enforced before private data is read? What happens when sensitivity changes mid-run?
  • Which policy belongs in repository, harness or operator configuration, and which trusted authority can approve an exception?
  • Which tasks can use a bounded prefetch, and which need scoped retrieval? What evidence would justify expanding the selected context?
  • Who approves a private-to-public work-item handoff, and how are its content, derived behavior and subsequent updates checked without exposing private rationale or linkage?
  • What console metadata is acceptable, including errors and timing signals?
  • How should fixed public results be bound to a revision and authorized publisher, and how should stale or unavailable evidence affect merge?
  • Can useful publication permissions be expressed once across built-in and custom agents without relying on prompt-only compliance?
  • Which free-form outputs require human approval, and how is that approval recorded without disclosing its private supporting evidence?
  • How do private artifact readers, resumption and retro avoid expanding the original audience? What retention and deletion guarantees are needed?
  • Which configurations should be rejected until their complete execution and publication paths can honor the selected boundary?