C6
Developer Tools AWS

CodeChecker 6.29.3 on AWS User Guide

| Product: CodeChecker 6.29.3 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the CodeChecker 6.29.3 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Apache Subversion (SVN) & CI/CD Tools listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

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

The cloudimg image adds:

  • 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 the moment the instance boots, and unattended upgrades keep them patched.
  • Authentication on from the first request. Upstream CodeChecker ships with authentication switched off, which lets anyone who reaches the port read every stored finding (file paths, source lines, 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's password is created on your instance's first boot and only its hash is 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 it cannot finish, CodeChecker stays offline rather than 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 token you create for the purpose (Step 10), revocable at any time, so no CI machine holds the administrator password.
  • A rate-limited login. 60 sign-in requests a minute from one address (with a burst of 60), in every spelling of the endpoint, and 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 cloudimg-sample-c, so you see real findings with real bug paths when you first 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. cloudimg is not affiliated with, endorsed by, or sponsored by any of them.

Prerequisites

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

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick CodeChecker 6.29.3 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (analysis of large code bases on the instance itself wants more cores), your key pair and a security group as above.

Step 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>

Step 3: Check the services

First boot takes about a minute. Then 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; 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, and 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

Step 4: The release and the analysers

How CodeChecker was installed:

cat /usr/share/doc/codechecker-cloudimg/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-cloudimg/requirements.txt lists the 58 hash-pinned Python packages in the virtualenv. CodeChecker is a driver: it runs other analysers. Ask it what 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 cloudimg 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 shipped; it is a large toolchain of its own and is better installed deliberately if you need it. The Clang and Cppcheck packages are in Ubuntu's universe component, which Ubuntu Pro (esm-apps) covers with security updates.

Step 5: Get your sign-in details

The credentials file holds the address CodeChecker is served on and the administrator account, 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 holds 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).

Step 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, and compare it with what 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 = cloudimg
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 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.

Step 7: Sign in

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

The CodeChecker sign-in page

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

The CodeChecker products page with the Default product, signed in as ccadmin

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

The runs of the Default product: cloudimg-sample-c with 7 unresolved reports from clangsa and clang-tidy

Step 8: Read the sample findings

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

The report list of cloudimg-sample-c: seven findings from the Clang Static Analyzer and Clang-Tidy

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

A report's detail view: the source of null_deref.c with the numbered bug path steps

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

The statistics of the Default product: new and resolved reports, failed files and checkers reporting faults

The same from the command line. SSL_CERT_FILE makes the CodeChecker client trust exactly this instance's certificate, and the password goes to 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 cloudimg-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
cloudimg-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.

Step 9: Analyse your own project

CodeChecker needs a compilation database, compile_commands.json, that says 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. A throwaway example:

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.

Step 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. It 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 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 only 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), 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

Then give the client the token in ~/.codechecker.passwords.json (mode 0600, keyed on the host and port of the URL) and store 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 store. The same flow, on the instance, with a home directory that holds nothing but 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.

Step 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 it under another name:

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

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

Step 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 it 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 it access: as ccadmin, 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, giving it 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

Step 13: 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.

Step 14: Security checks

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=admin /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: only nginx listens on the network. The same refusal holds from outside the instance, for example curl -m 5 http://<public-ip>:8001/ from your workstation.

Step 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

Stop the server for a consistent copy of the SQLite databases, archive the workspace and copy it 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: they hold your account material. CodeChecker itself is pinned in its virtualenv and is not upgraded automatically, because its database schema is tied to the release; upgrade it deliberately, after a backup.

Step 16: Security recommendations

  • Keep TCP 443 and 80 open only to your team's networks and your CI machines; 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

cloudimg provides 24/7 technical support for this image by email and live chat: support@cloudimg.co.uk or https://www.cloudimg.co.uk/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-cloudimg/LICENSE.TXT. The Clang tools, Cppcheck and GCC are Ubuntu archive packages under their own licences (see /usr/share/doc/<package>/copyright). cloudimg is not affiliated with, endorsed by, or sponsored by Ericsson, the LLVM Foundation or the Cppcheck project.