Skip to main content

Getting started

After this guide, CodeGuard is installed, finds its tools and has checked a first project.

Requirements​

WhatRequirement
Operating systemmacOS 15 or later. The target minimum is 15.6; certification for it is still pending.
To build CodeGuardSwift toolchain with swift-tools-version 6.3
XcodeFor swift-format, swift, xcodebuild and simctl. xcodebuild must have a version >= 26.0.0 and < 28.0.0.
swift-formatFrom the active Xcode toolchain. Supported are 6.3.x and the unversioned build from Xcode 27 (reports itself as main).
swiftlintRequired by default. If it is missing, every check run ends with exit 3.
gitFor check-diff, resolved from a trusted directory (e.g. /usr/bin).
What this help was created with

The sample output in this help comes from real runs of codeguard 0.3.5 on macOS 27.0.1 (Apple Silicon) with Xcode 27.0 (build 27A266a), SwiftLint 0.65.1 and iOS simulator runtime 27.0. On other versions, version numbers, durations and device names may differ.

Installation​

CodeGuard is built from source. The install script builds in release mode as your user and then uses sudo to copy the binary and the three resource bundles into the same directory, owned by root:wheel.

  1. Get the source code:

    git clone <REPOSITORY-URL> CodeGuard # placeholder: enter the repository URL
    cd CodeGuard
  2. Build and install:

    Scripts/install.sh # installs to /usr/local/bin
    Scripts/install.sh --bindir DIR # installs to DIR

    The script refuses to run as root. It only calls sudo for copying.

  3. Verify the installation:

    codeguard version
    codeguard 0.3.5 (configuration schema 1, report schema 1)

These bundles must sit next to the binary:

  • CodeGuard_CodeGuardConfiguration.bundle
  • CodeGuard_CodeGuardReporting.bundle
  • CodeGuard_CodeGuardAnalysis.bundle

If one is missing, every command aborts with exit 9 and reports installation incomplete: resource bundle … not found next to the codeguard executable. So never copy the binary on its own.

Set up the organization policy​

CodeGuard only starts tools from trusted directories (trusted_roots). Without your own policy, these defaults apply:

/usr/bin
/usr/local/bin
/opt/homebrew/bin
/Applications/Xcode.app/Contents/Developer/usr/bin

A standard Xcode installation, however, ships swift-format and swift under /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin. Without a policy, doctor therefore reports swift-format: unavailable, checks of .swift files end with exit 6, and the SwiftPM build can end with exit 3. A project configuration can't fix this; tool paths belong to the organization policy.

  1. Create the policy (template from the repository, docs/help/policy.example.yml):

    policy_version: 1
    configuration_versions: [1]
    enforcement:
    tools:
    trusted_roots:
    - /usr/bin
    - /usr/local/bin
    - /Applications/Xcode.app/Contents/Developer/usr/bin
    - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  2. Install it with the correct permissions. The file and all directories above it must be owned by root and must not be group- or world-writable:

    sudo mkdir -p "/Library/Application Support/CodeGuard"
    sudo install -o root -g wheel -m 0644 docs/help/policy.example.yml \
    "/Library/Application Support/CodeGuard/policy.yml"
  3. Verify:

    codeguard config validate

    The output names the policy with its hash, for example:

    configuration valid (schema 1, sha256:b6d2da11a83b32a5c08fd1941bc85affa4a50ed7ec50c93d975457ff05a23dad)
    policy: /Library/Application Support/CodeGuard/policy.yml (sha256:22a9eaedcf877ffbbdcbcaad6d510810c334a29c194ea81404cd2eca324aee80)

All policy keys are listed on the Organization policy page.

Provide SwiftLint​

SwiftLint doesn't ship with Xcode. CodeGuard only looks for it under the trusted directories.

No Homebrew paths as trusted directories

/opt/homebrew/bin and /opt/homebrew/Cellar/… belong to the user who installed Homebrew. Any process of that user, such as a SwiftPM plugin, could replace swiftlint there while the root-owned policy keeps trusting it. CodeGuard doesn't check the owner of a trusted directory itself.

Create a root-owned copy instead:

sudo install -o root -g wheel -m 0755 "$(realpath /opt/homebrew/bin/swiftlint)" /usr/local/bin/swiftlint

Repeat this after every brew upgrade swiftlint. On Apple silicon Macs, /usr/local/bin is owned by root. On Intel Macs it is usually owned by Homebrew; in that case, create another root-owned directory and add it to trusted_roots.

Not two roots for the same tool

If CodeGuard finds a tool under two trusted directories (for example a symlink in one root and its target in another), the resolver rejects it as ambiguous. doctor then shows the tool as unavailable.

Check your environment​

codeguard doctor

Output on the reference machine, run in an empty folder (hence compile/tests: inactive):

ready: true
policy: /Library/Application Support/CodeGuard/policy.yml (sha256:22a9eaedcf877ffbbdcbcaad6d510810c334a29c194ea81404cd2eca324aee80)
configuration: active
git-diff: active
path-policy: active
read-only-checks: active
reports: active
trust-state: active
swift-format: active (main)
swiftlint: active
compile: inactive
tests: inactive
autofix: inactive
agent-adapters: inactive
platform-checks: active (1)
content-rules: active (secret-detectors-v1)
unauthorized-network-destination: inactive
platform.macos: available (27.0)
platform.ios: available (27.0)
platform.watchos: available (27.0)
platform.tvos: available (27.0)
platform.visionos: available (27.0)
simctl: active (1171.7.0) /Applications/Xcode.app/Contents/Developer/usr/bin/simctl
simulator.ios: available (device type: iPhone 18 Pro)
simulator.ios.runtime: 27.0 (24A434)
simulator.ios.runtime: 26.5 (23F77)
simulator.ios.runtime: 18.5 (22F77)
simulator.watchos: unavailable
simulator.tvos: unavailable
simulator.visionos: unavailable
Verwaiste CodeGuard-Geräte: 0

How to read the output:

StatusMeaning
activeThe capability is available
unavailableTool enabled but can't be resolved
incompatibleTool found, but the version doesn't match
inactiveDisabled or not relevant in this context
  • ready: true means every enabled format and lint check is ready to use.
  • platform.<name> shows whether the SDK is installed, simulator.<name> whether a simulator runtime exists for it. In the example, all SDKs are present, but only iOS runtimes. Tests for watchOS, tvOS and visionOS would therefore be skipped.
  • doctor never runs a lint or a build. It only determines paths and versions.

First check run​

  1. Change to the root of your project (where Package.swift or the .xcodeproj is).

  2. Check a single file:

    codeguard check-file Sources/MeinModul/Datei.swift
  3. Check your Git changes against main:

    codeguard check-diff --base main --include-untracked

    Without a trust ticket, this ends with CODEGUARD_BLOCKED and exit 6 for projects with a Package.swift or Xcode project, because compile and tests would run project code. The static checks still run and appear in the report.

  4. Grant trust to the project (in the terminal, confirm with yes):

    codeguard trust grant --duration 24h

    After that, check-diff builds and tests the project. For more, see Trust and security.

tip

The day-to-day workflow is described under Manual use, the meaning of every line in the report under Reading reports.

See also​