Deployment guide

CodeChecker 6.29.3

Overview

This guide shows how to launch and use the CodeChecker 6.29.3 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. The AMI is one software version of the SecureAnyCloud Hardened Apache Subversion (SVN) & CI/CD Tools listing on AWS Marketplace. Select it as the software version when you subscribe and launch.

CodeChecker is an open source static analysis platform for C and C++. It runs established analysers over your source and stores everything they report as a named run in a database. Your team triages the results in a web interface: mark a finding as a real bug or a false positive, comment on it, and see whether a defect is new, outstanding or fixed compared with an earlier run. A reviewer can open a link to a single defect with its full execution path laid over the source.

What you get:

  • The analysers ship with it. The Clang Static Analyzer and Clang-Tidy 18, Cppcheck 2.13 and GCC 13 come from the Ubuntu 24.04 archive, so you can analyse a project as soon as the instance boots, and unattended upgrades keep them patched.
  • Authentication on from the first request. Upstream CodeChecker ships with authentication switched off, so anyone who reaches the port can read every stored finding (file paths, source lines and defect locations). This image refuses to start the server unless authentication is on and every configured account is a salted SHA-512 hash. The administrator password is created on your instance's first boot, and only its hash is stored in the server configuration.
  • Nothing shared between instances. The image ships no account, no database and no certificate. First boot creates the administrator password, the HTTPS certificate and the empty results database on your instance. The server and nginx do not start until first boot has finished. If first boot cannot finish, CodeChecker stays offline instead of open.
  • HTTPS from the first boot. nginx serves CodeChecker on port 443 with a certificate generated on your instance (it names the instance's public and private addresses and DNS names). Port 80 redirects to HTTPS. CodeChecker itself listens on 127.0.0.1:8001 only.
  • CI uploads with personal access tokens. CodeChecker store authenticates with a revocable token that you create for this purpose (Step 10), so no CI machine holds the administrator password.
  • A rate-limited login. The sign-in endpoint accepts 60 requests a minute from one address (with a burst of 60), in every spelling of the endpoint, and the server accepts 1,200 requests a minute overall. A sign-out reaches every server worker within 15 seconds.
  • Metadata service blocked for CodeChecker, nginx, the first-boot service and the helper commands. The AMI requires IMDSv2.
  • A sample analysis on day one. A small C project with deliberate defects ships with the image. First boot stores its analysis as the run sac-sample-c, so you see real findings with real bug paths the first time you sign in.
  • A hash-pinned install. CodeChecker runs from a root-owned Python 3.12 virtualenv built from 58 hash-pinned packages, as its own codechecker user, which can write only to its workspace.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

Trademark notice: CodeChecker is an open source project maintained by Ericsson AB under Apache-2.0 WITH LLVM-exception. "Ericsson" is a trademark of Telefonaktiebolaget LM Ericsson; "LLVM" and "Clang" are trademarks of the LLVM Foundation. They are named here only to describe the software and the analysers it drives. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by any of them.

Prerequisites

  • An AWS account that is subscribed to the listing, an EC2 key pair, and a VPC subnet with a route to the internet (or a private route that you use for management).
  • A security group that allows inbound TCP 443 (CodeChecker's web interface and CodeChecker store) and TCP 80 (redirects to HTTPS) from the networks that should reach them, meaning your team's browsers and every CI machine that uploads results. Allow TCP 22 (SSH) from your own networks only. Do not open port 8001, because CodeChecker listens on loopback only.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Select CodeChecker 6.29.3 on Ubuntu 24.04 as the software version, pick your Region, and choose Launch through EC2.

Select m5.large as the instance type (analysing large code bases on the instance itself needs more cores). Then choose your key pair and the security group described in Prerequisites.

2

Connect to your instance

Version SSH user

CodeChecker 6.29.3 on Ubuntu 24.04 ubuntu

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

First boot takes about a minute. When it finishes, CodeChecker, nginx and the first-boot unit are active:

systemctl is-active codechecker nginx codechecker-firstboot
active active active

nginx serves ports 80 and 443, and CodeChecker listens on loopback only, so the only open ports are 22, 80 and 443:

sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|CodeChecker/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer LISTEN 127.0.0.1:8001 users:(("CodeChecker"),("CodeChecker"),("CodeChecker"),("CodeChecker")) LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) LISTEN 0.0.0.0:22 users:(("sshd"),("systemd")) LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx")) LISTEN [::]:22 users:(("sshd"),("systemd")) LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))

/live answers load-balancer health checks on both ports without touching any product data. Every other request to port 80 is redirected to HTTPS:

curl -s --cacert /etc/nginx/ssl/codechecker.crt https://127.0.0.1/live
curl -s -o /dev/null -w 'port 80: %{http_code}\n' http://127.0.0.1/
ok port 80: 301
4

Check the release and the analysers

Check how CodeChecker is installed:

cat /usr/share/doc/codechecker-sac/RELEASE
CodeChecker 6.29.3 (Apache-2.0 WITH LLVM-exception), PyPI sdist sha256 13a01fd7250ebf107af9c3f338745654c5efe0320c3db9e5f8744d4db0510b02 client-api 6.74 requirements-sha256 a5ad31e0a17e3d8c047af20fe5b93e4edc4cbab7959076b9ea265456b60ab18f python 3.12.3 built 2026-11-07

/usr/share/doc/codechecker-sac/requirements.txt lists the 58 hash-pinned Python packages in the virtualenv. CodeChecker is a driver that runs other analysers. List the analysers it can use:

/opt/codechecker/venv/bin/CodeChecker analyzers --details 2>/dev/null
sudo cat /etc/codechecker/analyzer-versions.txt
clangsa /usr/lib/llvm-18/bin/clang 18.1.3 clang-tidy /usr/lib/llvm-18/bin/clang-tidy 18.1.3 cppcheck /usr/bin/cppcheck 2.13.0 gcc /usr/bin/x86_64-linux-gnu-g++-13 13.3.0 infer NOT FOUND
# Analyser toolchain shipped in this sac CodeChecker image (Ubuntu 24.04 archive packages). clang=Ubuntu clang version 18.1.3 (1ubuntu1) clang-tidy=Ubuntu LLVM version 18.1.3 cppcheck=Cppcheck 2.13.0 gcc=gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 gpp=g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 python3=Python 3.12.3

Facebook Infer is not included because it is a large toolchain of its own. Install it separately if you need it. The Clang and Cppcheck packages are in Ubuntu's universe component, which Ubuntu Pro (esm-apps) covers with security updates.

5

Get your sign-in details

The credentials file holds the address that CodeChecker is served on and the administrator account, both generated on this instance:

sudo cat /root/codechecker-credentials.txt
CODECHECKER_URL=https://<public-ip>/ codechecker.admin.user=ccadmin codechecker.admin.pass=<28 letters and digits>

ccadmin is the server's super user: it administers products and grants access to other users. The password comes from the kernel's random number generator on first boot and is known to nobody else. The server configuration stores only a salted SHA-512 hash of it:

sudo python3 -c "import json; e=json.load(open('/etc/codechecker/server_config.json'))['authentication']['method_dictionary']['auths'][0].split(':'); print('user :', e[0]); print('algorithm :', e[2]); print('hash :', len(e[1]), 'hex digits'); print('salt :', len(e[3]), 'hex digits')"
sudo /usr/local/sbin/codechecker-assert-auth
user : ccadmin algorithm : sha512 hash : 128 hex digits salt : 32 hex digits codechecker-assert-auth: OK - authentication enabled, 1 salted sha512 credential(s)

codechecker-assert-auth runs before every start of the server. It refuses to start CodeChecker if authentication is off, if any account is stored in plain text, if the super user has no account, or if LDAP, PAM or OAuth sign-in is switched on (this image authenticates against its own accounts only).

6

Check the certificate

The HTTPS certificate is self-signed and was generated on your instance. Before you trust it in a browser or on a CI machine, note its fingerprint here over SSH. Then compare it with the fingerprint that your browser or openssl shows from outside (Step 10):

openssl x509 -in /etc/nginx/ssl/codechecker.crt -noout -subject -enddate -fingerprint -sha256 -ext subjectAltName | sed -E 's/[0-9]+(\.[0-9]+){3}/<ip>/g; s/ec2-[0-9-]+/ec2-<ip>/g; s/ip-[0-9-]+/ip-<ip>/g; s/=([0-9A-F]{2}:){31}[0-9A-F]{2}/=<64 hex digits>/'
subject=CN = ec2-<ip>.compute-1.amazonaws.com, O = sac notAfter=Feb 9 10:10:24 2029 GMT sha256 Fingerprint=<64 hex digits> X509v3 Subject Alternative Name: IP Address:<ip>, IP Address:<ip>, DNS:localhost, IP Address:<ip>, DNS:ec2-<ip>.compute-1.amazonaws.com, DNS:ip-<ip>.ec2.internal

The sed command only hides this example's addresses. Run the openssl command on its own to see yours. Step 13 shows how to use your own DNS name and certificate.

7

Sign in

Open https://<public-ip>/ in your browser. After you check the fingerprint, confirm the certificate exception. Anyone who is not signed in sees the sign-in page and nothing else:

Sign in as ccadmin with the password from Step 5. The products page lists Default, the product that CodeChecker creates when the server starts, backed by a SQLite database in the workspace:

Open Default. The sac-sample-c run was stored on first boot:

8

Read the sample findings

The REPORTS tab lists the run's seven findings with their checker, severity and bug path length:

Open a finding to see the path that leads to the defect, step by step, over the source:

The STATISTICS tab summarises a run by checker and severity, and tracks new and resolved reports over time:

You can do the same from the command line. SSL_CERT_FILE makes the CodeChecker client trust exactly this instance's certificate. The password reaches the client through its CC_PASSWORD environment variable, never on a command line:

export PATH=/opt/codechecker/venv/bin:$PATH SSL_CERT_FILE=/etc/nginx/ssl/codechecker.crt CC_PASSWORD="$(sudo sed -n 's/^codechecker.admin.pass=//p' /root/codechecker-credentials.txt)" CodeChecker cmd login ccadmin --url https://127.0.0.1 2>&1 | tail -1 CodeChecker cmd runs --url https://127.0.0.1/Default -o csv 2>/dev/null | cut -d, -f1,2 CodeChecker cmd results sac-sample-c --url https://127.0.0.1/Default -o csv 2>/dev/null | cut -d, -f1-3
[INFO 2026-11-07 10:14:02] - Server reported successful authentication. Name,Number of unresolved reports sac-sample-c,7 File,Checker,Severity /opt/codechecker/sample-project/src/uninit_value.c @ 8,clang-diagnostic-uninitialized,HIGH /opt/codechecker/sample-project/src/uninit_value.c @ 8,core.uninitialized.Assign,HIGH /opt/codechecker/sample-project/src/uninit_value.c @ 10,core.uninitialized.UndefReturn,HIGH /opt/codechecker/sample-project/src/div_zero.c @ 16,core.DivideZero,HIGH /opt/codechecker/sample-project/src/null_deref.c @ 24,core.NullDereference,HIGH /opt/codechecker/sample-project/src/null_deref.c @ 13,cert-err33-c,MEDIUM /opt/codechecker/sample-project/src/mem_leak.c @ 22,unix.Malloc,MEDIUM

The login session is saved in ~/.codechecker.session.json (readable only by you) and lasts an hour. CodeChecker cmd login --logout --url https://127.0.0.1 ends it.

9

Analyse your own project

CodeChecker needs a compilation database, compile_commands.json, that records how each file is compiled. With CMake, ask for it with cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON; with make or any other build, let CodeChecker watch the build with CodeChecker log. The following example uses a small throwaway project:

export PATH=/opt/codechecker/venv/bin:$PATH mkdir -p /tmp/demo-project && cd /tmp/demo-project printf '#include <stdlib.h>\nint main(void) {\n int *p = malloc(sizeof(int));\n return *p;\n}\n' > example.c printf 'example.o: example.c\n\tgcc -c example.c -o example.o\n' > Makefile CodeChecker log --build "make" --output ./compile_commands.json 2>&1 | tail -1 CodeChecker analyze compile_commands.json -o ./reports --analyzers clangsa clang-tidy 2>&1 | tail -1 CodeChecker parse ./reports 2>/dev/null | head -4 || true
[INFO 2026-11-07 10:14:05] - Build finished successfully. [INFO 2026-11-07 10:14:06] - Analysis length: 0.44 sec. [HIGH] /tmp/demo-project/example.c:4:5: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] return *p; ^

CodeChecker parse exits with 2 when it finds defects, so a CI job can fail a build on them (hence the || true here). Store the analysis as a run, signed in as in Step 8:

export PATH=/opt/codechecker/venv/bin:$PATH SSL_CERT_FILE=/etc/nginx/ssl/codechecker.crt cd /tmp/demo-project && CodeChecker store ./reports --name demo-project --url https://127.0.0.1/Default 2>&1 | tail -1
[INFO 2026-11-07 10:14:12] - Storing the reports finished successfully.

demo-project now appears on the RUNS tab. Store each analysis of a code base under the same run name to see what is new and what is resolved between builds.

10

Upload from CI with a personal access token

CodeChecker store talks to the server over HTTPS, so your CI machines need TCP 443 to the instance and nothing else. Do not give them the administrator password. Create a personal access token for them instead. A token works in place of the password, expires after the number of days you choose (1 to 365) and can be revoked at any time. Create one and save it to a file that only you can read (the token is not printed):

export PATH=/opt/codechecker/venv/bin:$PATH SSL_CERT_FILE=/etc/nginx/ssl/codechecker.crt umask 077 CodeChecker cmd token new ci-store --expiration 90 --description "CI uploads" --url https://127.0.0.1 2>/dev/null | sed -n 's/^The following access token has been generated for your account: //p' > ~/ci-store.token echo "token saved: $(tr -d '\n' < ~/ci-store.token | wc -c) characters"
token saved: 32 characters

Copy ~/ci-store.token to your CI system's secret store and delete it here. Tokens are listed with CodeChecker cmd token list and revoked with CodeChecker cmd token del <name> (both with --url https://127.0.0.1). A token carries the permissions of the user who created it. For least privilege, create a CI user (Step 12), grant it access only to the products it uploads to, and create the token as that user.

On each CI machine, install the CodeChecker client of the same release (pip install codechecker==6.29.3). Then fetch the server's certificate and check its fingerprint against Step 6:

openssl s_client -connect <public-ip>:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > codechecker.crt
openssl x509 -in codechecker.crt -noout -fingerprint -sha256

Next, give the client the token in ~/.codechecker.passwords.json (mode 0600, keyed on the host and port of the URL) and store results as usual. The client signs in by itself:

{"client_autologin": true, "credentials": {"<public-ip>:443": "ccadmin:<token>"}}
export SSL_CERT_FILE=$PWD/codechecker.crt CodeChecker store ./reports --name my-project --url https://<public-ip>:443/Default

Alternatively, sign in once per job with CC_PASSWORD=<token> CodeChecker cmd login ccadmin --url https://<public-ip>:443 and then store. The following example runs the same flow on the instance, with a home directory that holds only the token:

export PATH=/opt/codechecker/venv/bin:$PATH SSL_CERT_FILE=/etc/nginx/ssl/codechecker.crt
CI_HOME=$(mktemp -d) && umask 077 printf '{"client_autologin": true, "credentials": {"127.0.0.1:443": "ccadmin:%s"}}\n' "$(tr -d '\n' < ~/ci-store.token)" > "$CI_HOME/.codechecker.passwords.json" cd /tmp/demo-project && HOME="$CI_HOME" CodeChecker store ./reports --name demo-project-ci --url https://127.0.0.1/Default 2>&1 | tail -1 rm -rf "$CI_HOME"
[INFO 2026-11-07 10:14:19] - Storing the reports finished successfully.

Each CodeChecker command signs in through the rate-limited endpoint, so a single address can run about 60 commands a minute before it is slowed down with HTTP 429.

11

Re-run the sample analysis

codechecker-analyze-sample analyses the bundled sample project and stores it, a quick end-to-end check after any change. It reads the administrator password itself, so run it with sudo. Pass a run name to store the analysis under a different name:

sudo codechecker-analyze-sample 2>&1 | sed -n '1,3p'
==> Analysing /opt/codechecker/sample-project (clangsa + clang-tidy) ==> Storing run 'sac-sample-c' ==> Findings stored in 'sac-sample-c':

Delete sac-sample-c from the RUNS tab whenever you no longer want it.

12

Users, permissions and products

Users. Accounts live in /etc/codechecker/server_config.json under authentication.method_dictionary.auths, one user:hash:sha512:salt entry each, where the hash is the SHA-512 of the password followed by the salt. Generate an entry (the password is printed once; keep it somewhere safe):

python3 -c " import hashlib, secrets, string pw = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(28)) salt = secrets.token_hex(16) print('password :', pw) print('entry : reviewer:%s:sha512:%s' % (hashlib.sha512((pw + salt).encode()).hexdigest(), salt)) "

Add the entry to the auths list, check the file and restart the server:

sudo nano /etc/codechecker/server_config.json
sudo /usr/local/sbin/codechecker-assert-auth && sudo systemctl restart codechecker

A new user can sign in but sees no product until you grant access. Sign in as ccadmin and use EDIT GLOBAL PERMISSIONS on the products page, or the pencil icon of a product to grant product permissions (PRODUCT_VIEW, PRODUCT_STORE, PRODUCT_ACCESS, PRODUCT_ADMIN).

Products. A product is a separate results database, usually one per code base. Add one from the products page or with the client. Each product gets its own SQLite file in the workspace:

CodeChecker cmd products add myproduct --name "My Product" --sqlite /var/lib/codechecker/workspace/myproduct.sqlite --url https://127.0.0.1
13

Use your own DNS name and certificate

Point a DNS name at the instance (an Elastic IP keeps the address across stops). Then replace /etc/nginx/ssl/codechecker.crt and codechecker.key with your certificate chain and key (key mode 0600, owned by root) and reload nginx:

sudo nginx -t && sudo systemctl reload nginx

With a certificate from a public CA, CI machines and browsers need no SSL_CERT_FILE or exception. You can also put an Application Load Balancer in front of the instance. Point its health check at /live on port 443.

14

Run the security checks

These checks confirm that an API call without a session is refused, a wrong password is refused, CodeChecker cannot be reached on its own port from the network, and none of the services can reach the instance metadata service:

curl -s --cacert /etc/nginx/ssl/codechecker.crt -X POST https://127.0.0.1/v6.74/Products -H 'Content-Type: application/x-thrift' --data '[1,"getProducts",1,0,{}]'; echo
T=$(mktemp -d); SSL_CERT_FILE=/etc/nginx/ssl/codechecker.crt HOME="$T" CC_PASSWORD=<set-at-first-boot> /opt/codechecker/venv/bin/CodeChecker cmd login ccadmin --url https://127.0.0.1 2>&1 | tail -2 || true; rm -rf "$T"
curl -s -m 5 -o /dev/null -w 'CodeChecker on the private address: %{http_code}\n' "http://$(hostname -I | awk '{print $1}'):8001/" || true systemctl show -p IPAddressDeny codechecker nginx codechecker-firstboot
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
[1,"getProducts",3,0,{"1":{"str":"Error code 401: Unauthorized!"},"2":{"i32":6}}] Invalid credentials supplied for user 'ccadmin'. Refusing authentication! Note: Invalid credentials. CodeChecker on the private address: 000 IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 permitrootlogin no passwordauthentication no

000 means the connection was refused, because only nginx listens on the network. The same refusal applies from outside the instance, for example curl -m 5 http://<public-ip>:8001/ from your workstation.

15

Your data and backups

What Where

Products, users' sessions, tokens and one SQLite database per product /var/lib/codechecker/workspace

Server configuration and accounts /etc/codechecker/server_config.json

The administrator's password /root/codechecker-credentials.txt

HTTPS certificate and key /etc/nginx/ssl/

CodeChecker (read only to the server) /opt/codechecker/venv

To take a consistent copy of the SQLite databases, stop the server, archive the workspace and copy the archive off the instance (to S3, for example):

sudo systemctl stop codechecker
sudo tar czf /root/codechecker-workspace-$(date +%F).tar.gz -C /var/lib/codechecker workspace
sudo systemctl start codechecker

Back up server_config.json and the credentials file separately because they hold your account material. CodeChecker is pinned in its virtualenv and is not upgraded automatically, because its database schema is tied to the release. Upgrade it deliberately, and take a backup first.

16

Security recommendations

  • Keep TCP 443 and 80 open only to your team's networks and your CI machines, because stored findings describe your source code in detail.
  • Use personal access tokens with an expiry for CI, one per pipeline, and revoke them when a pipeline is retired.
  • Give reviewers their own accounts with only the products they need, and keep ccadmin for administration.
  • Replace the self-signed certificate with your own (Step 13) before you share the address widely.
  • Keep the instance patched: unattended upgrades cover Ubuntu and the analysers; upgrade CodeChecker with a backup taken first.

Support and licensing

SecureAnyCloud provides 24/7 technical support for this image by email and live chat: sales@secureanycloud.com or https://secureanycloud.com/support. Include the instance type, the Region and the output of Steps 3 and 14.

CodeChecker is released under Apache-2.0 WITH LLVM-exception; its licence is at /usr/share/doc/codechecker-sac/LICENSE.TXT. The Clang tools, Cppcheck and GCC are Ubuntu archive packages under their own licences (see /usr/share/doc/<package>/copyright). SecureAnyCloud is not affiliated with, endorsed by, or sponsored by Ericsson, the LLVM Foundation or the Cppcheck project.

Deploy on AWS

Launch CodeChecker 6.29.3 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS