Custom transports
Use explicit instrumentation when GrantTrace's automatic Node preload cannot observe your GitHub client.
You normally do not need to change your code. granttrace record and
granttrace prove inject a Node preload that observes supported GitHub REST
requests made through global fetch to exactly https://api.github.com.
Standard Octokit clients use that transport and are covered automatically.
The automatic path ignores off-origin requests even when their response
supplies a permission-like header.
Automatic recording is deliberately bounded. It does not observe a client that:
- replaces global
fetchwith a custom implementation; - uses a custom Octokit transport or wrapper that bypasses global
fetch; - runs the request in a subprocess or worker that discards the injected Node options;
- runs outside Node.js; or
- targets an unsupported GitHub Enterprise endpoint.
These requests are outside the contract unless you route them through the explicit integration below.
Explicit fallback
import { GrantTraceOctokit } from "granttrace/octokit";
export function createGitHubClient(token: string) {
return new GrantTraceOctokit({ auth: token });
}Use that factory everywhere the scenario creates a GitHub client. Any second
client that bypasses both global fetch and this adapter remains unobserved.
The pre-composed constructor uses GrantTrace's exact compatible Octokit
dependency.
Advanced Octokit composition
If the project must combine GrantTrace with other Octokit plugins, manual composition remains supported with the exact compatible core version:
import { Octokit } from "@octokit/core";
import { grantTrace } from "granttrace/octokit";
const TracedOctokit = Octokit.plugin(grantTrace);Use exactly @octokit/core@7.0.6. Other core versions and third-party wrappers
are outside the explicit beta compatibility claim. Prefer
GrantTraceOctokit unless composition is necessary.
Runtime behavior
The explicit plugin is inert during normal application execution. When the
process is launched by granttrace record or granttrace prove, it:
- pins the GitHub REST API to
2026-03-10; - reads the pre-expansion Octokit route template;
- observes the accepted-permissions header on success and error responses; and
- writes a new safe observation containing only allowlisted fields.
An explicitly conflicting API version fails instead of recording evidence against the wrong catalog.
Keep route templates intact
When using the explicit adapter, call Octokit with canonical route templates:
await octokit.request(
"POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
{
owner,
repo,
issue_number: issueNumber,
body: "Looks good",
},
);Concrete URLs, absolute URLs, query-bearing route strings, GraphQL, and unmatched templates are not heuristically redacted. They become blocking safe findings.
Authentication boundary
Recording observes route behavior; it does not authenticate or prove that the configured credential is a GitHub App installation token. Use a dedicated GitHub App test setup, and treat the accepted contract as scenario-bound route evidence rather than an authentication audit.
For a repository example, see
examples/triage-bot.
It uses a local fixture and the explicit adapter to demonstrate a hermetic
consumer workflow; the fixture omits runtime permission evidence, so the
result is catalog-backed.