Offline bundles let you use platform profiles and your own profiles in environments that have no direct internet access, such as air-gap CI systems or internal artifact repositories.
Why offline bundles
In some environments your CI runner is not allowed to reach the internet directly:
- Air-gap CI: Isolated build infrastructure without outbound connectivity to the portal.
- Internal artifact repository: Bundles are downloaded once and mirrored internally so every team accesses the same version.
- Regulatory requirements: Audited environments where external network connections from CI are prohibited or restricted.
Exporting a bundle from the portal
You can download a bundle for any published profile version from the portal:
- Open the profile list or the platform rules overview.
- On the profile list, click the kebab menu (⋮) on the desired profile card and select Download bundle. On the platform rules overview, click the Download bundle button directly on the profile card.
- Choose the version and download the signed
.cgbundlefile.
The bundle contains all rule files (.cgr) for the pinned version, a manifest
file with metadata and a content hash, and an Ed25519 signature.
Referencing a bundle file in .codecharter/config.yml
Instead of an API call to the portal you can reference a locally available bundle
directly. The path key accepts both local file paths and HTTPS mirror URLs:
# .codecharter/config.yml
version: 1
profiles:
- path: ".codecharter/bundles/dotnet-standard-2.1.0.cgbundle"
The CLI verifies the bundle signature each time the bundle is loaded and caches
it under .codecharter/cache/. CODECHARTER_API_KEY does not need to be set for
file-based usage. If a referenced bundle file does not exist, the CLI reports an
error for that entry and skips it; a failed signature check, by contrast, aborts
the run.
Recommendation: do not commit the bundle directly to the repository. Instead, download it from your internal mirror in a preceding CI step.
Setting up an internal mirror
You can mirror bundles behind an internal HTTPS URL using the same path key:
# .codecharter/config.yml
version: 1
profiles:
- path: "https://artifacts.internal.example.com/codecharter/dotnet-standard-2.1.0.cgbundle"
Mirror requirements:
- HTTPS only --
http://URLs are rejected. The certificate must be trusted by the operating system's certificate store; there is no CLI option to override certificate validation. - Immutable URLs per version -- the CLI downloads each URL once and reuses the cached file afterwards.
- The mirror URL must be reachable without authentication. The CLI does not send any credentials or authentication headers to mirror URLs.
Signature verification
Every bundle is signed with the portal's Ed25519 signing key. The CLI verifies the signature before use. If verification fails, the build aborts with an error such as:
Bundle 'dotnet-standard-2.1.0.cgbundle': Bundle signature is invalid (key '<key-id>').
The bundle may have been tampered with.
CodeCharter fetches the portal's public signing keys from the portal and caches
them locally at .codecharter/cache/signing-keys.json, refreshing them
automatically when they are absent or older than 24 hours. There is no manual
key command. When the portal is unreachable, the CLI falls back to the cached
keys even if they are stale. For a fully offline runner this means the key
cache must be primed beforehand: run the CLI once with portal connectivity (or
copy a populated .codecharter/cache/signing-keys.json onto the runner) so that
signature verification can succeed without network access.
Update workflow in air-gap environments
In a fully isolated environment we recommend the following process:
- On a machine with internet access: download the new bundle from the portal.
- Upload the bundle to your internal artifact repository.
- Update the version in
.codecharter/config.yml. - On the internet-connected machine, run
codecharter update --portal-url <url> --api-key <key>to refresh the lockfile. This command requires portal connectivity and cannot run inside the air gap. - Merge
.codecharter/config.ymland.codecharter/codecharter.lock.jsonin a PR. - On the CI runner: reference the mirrored bundle via a
path:entry in.codecharter/config.yml(local file or internal HTTPS URL) and runcodecharter analyzeas usual.
Bundles referenced via path: are downloaded, verified, and cached
automatically when the analysis runs; no separate restore step is needed for
them.