Copyright The Linux Foundation and each contributor to CommunityBridge.
SPDX-License-Identifier: CC-BY-4.0
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
EasyCLA is the Linux Foundation's Contributor License Agreement service. It lets contributors sign ICLAs/CCLAs and gates GitHub PRs and Gerrit/GitLab reviews on CLA authorization. Third-party integrations: DocuSign (e-sign), DocRaptor (PDF), GitHub, Gerrit, GitLab, Auth0 (SSO), and Salesforce via the LFX Platform APIs.
The frontend consoles (Project/Corporate/Contributor) live in separate repositories — this repo is backend-only plus supporting scripts/infra. Do not look for UI code here.
cla-backend-go/— primary backend, Go. Powers/v3(EasyCLA v1, us-east-1) and/v4(EasyCLA v2, us-east-2, integrates with LFX Platform + Salesforce). Deployed as AWS Lambdas.cla-backend/— Serverless Framework deployment stack (us-east-1). The Python backend has been removed; the sole application code it still owns is the API Gateway authorizer (cla-backend/auth/main.go,cla-backend/auth/authorizer/). Otherwise it deploys Go binaries built elsewhere — the/v3API and worker lambdas (dynamo-events, metrics, zipbuilder, gitlab-repository-check, user-subscribe) fromcla-backend-go/, and the/v1//v2legacy-api-lambdafromcla-backend-legacy/.cla-backend-legacy/— Go module (owngo.mod): the Go implementation of the legacy/v1//v2API surface (replaced the Python backend). Built asbin/legacy-api-lambdaand deployed viacla-backend/serverless.ymlon the originalapi.*domains. Responses carryX-EasyCLA-Backend: cla-backend-legacyheaders; parity tooling lives underinternal/parity.cla-sss-base/— standalone Go module (owngo.mod): client for the Sanctions Screening Service (SSS).scripts/,utils/— operational shell/Python scripts (data audits, DynamoDB manipulation, deploys, credential rotation). Manyutils/*.shscripts operate directly against AWS environments.infra/— infrastructure config.tests/— functional/REST tests, Postman collections, py2go comparison tests.
Requires Go 1.25+. All commands run from cla-backend-go/.
make setup # one-time: install swagger, golangci-lint, goimports; sets up swagger venv
make swagger # regenerate API models/clients from swagger specs into gen/ (see below)
make build-mac # build local binary -> bin/cla-mac (build-linux for Linux)
make test # go test -v ./... with coverage
make lint # golangci-lint (v1.64.8, config .golangci.yaml) + license header check
make fmt # gofmt + goimports
make mock # regenerate mocks via tools/regenmocks.sh
make all-mac # full pipeline: clean swagger deps fmt build test lint (all-linux on Linux)Run a single test: go test -v ./signatures/ -run TestName
Run locally (points at a real AWS environment — see below): build, set env, then ./bin/cla-mac (from make build-mac) or ./bin/cla (from make build-linux). Health checks at http://localhost:8080/v3/ops/health and /v4/ops/health. Set GH_ORG_VALIDATION=false to bypass GitHub auth checks for local curl/Postman testing.
The API is swagger-first. gen/ is fully generated and is deleted/rebuilt by make swagger — never hand-edit files under gen/. Source specs are multi-file YAML under swagger/ (cla.v1.yaml, cla.v2.yaml) compiled via swagger/multi-file-swagger.py. make swagger also downloads and generates clients for external LFX platform services (project-service, organization-service, user-service, acs-service) from their live dev swagger endpoints, so it requires network access. After changing an endpoint's spec, regenerate before implementing handlers.
Domain feature modules (e.g. signatures/, approval_list/, company/, project/, and most packages under v2/) follow a consistent three-layer split, though a module omits a layer it doesn't need (e.g. v2/health is handler-only, v2/project-service is a generated client with no handlers/service/repository):
handlers.go— aConfigure(api, service, ...)function that wires generated swagger operations to service calls. Handlers do request/response translation only.service.go— business logic, defined behind an interface; the unit-testable layer.repository.go— DynamoDB access.dbmodels.goholds table row structs;converters.gomaps between DB models, generated API models, and internal models.mocks/— generated mocks (regenerate withmake mock, don't edit by hand).
v2/ packages are the newer LFX-Platform-integrated implementations; top-level packages are v1/legacy. Both are wired together in cmd/server.go.
cmd/ holds main.go entrypoints for the many Lambda binaries (metrics, dynamo-events, zipbuilder, gitlab-repository-check, user-subscribe, etc.) plus the main API server (cmd/server.go, cmd/server_standalone.go, cmd/server_aws_lambda.go). Config is loaded from SSM via the init + config + token packages at startup.
Serves the legacy /v1//v2 API surface (the Python backend it replaced is gone). From the repo root:
source setenv.sh
cd cla-backend-legacy
go mod tidy
make lambdas # build deployment artifact bin/legacy-api-lambda
STAGE=dev ADDR=":5000" make run-local # run locally on :5000 pointing at dev environmentHealth check: http://localhost:5000/v2/health (response includes X-EasyCLA-Backend: cla-backend-legacy). Port 5000 matches the Cypress functional-test helpers (tests/functional/utils/run-single-test-local.sh with V=1/V=2).
Deployment: the built binary is copied into cla-backend/bin/ and deployed from the cla-backend Serverless stack (yarn deploy:dev, yarn deploy:staging, or yarn deploy:prod from cla-backend/).
Local backend runs point at real shared AWS environments (dev/test/staging/prod), not a local stack. The four environments map to AWS accounts via ~/.aws profiles lfproduct-dev, lfproduct-test, lfproduct-staging, lfproduct-prod (assume-role from lfproduct base profile, MFA required). See aws_env.md for the profile setup and dev.md for the assume-role helper script and required env vars (AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, PRODUCT_DOMAIN, ROOT_DOMAIN, STAGE).
Be careful: scripts in utils/ and scripts/ can mutate DynamoDB in whichever environment your profile targets, including prod.
- License headers are enforced in CI for source files (
.go,.py,.sh,.yaml/.yml,.txt— Markdown docs are not scanned) viacheck-headers.sh, which only checks for theCopyright The Linux Foundationline, not the SPDX identifier. New code files need// SPDX-License-Identifier: MIT; docs needSPDX-License-Identifier: CC-BY-4.0by convention, but the checker does not verify this. Onlycla-backend-go'smake lintinvokescheck-headers.sh;cla-backend-legacy'smake lint(go fmt + go vet) does not. - DCO required — every commit needs
Signed-off-by. - Use "Approved List" terminology, not "whitelist" (renamed across code, APIs, and specs as of 8/2025).
- Bot CLA exemptions: see
BOT_ALLOWLIST.md. Co-authors support: seeCO_AUTHORS.md. PR-check author/co-author caching design: seeCOMMIT_AUTHORS_CACHING.md.
GitHub Actions in .github/workflows/: build-pr.yml (build/test/lint), cypress-functional-pr.yml (functional E2E), CodeQL/security/license scans for the Go backends, and deploy-dev.yml / deploy-prod.yml for deployment (both build cla-backend-go and cla-backend-legacy, then deploy through the cla-backend stack).