Local development uses deployments/docker-compose.yaml. The default configuration uses LocalStack to simulate AWS services. All workflows use make targets, which handle dependency ordering.
For architecture, deployment topology, and the security model, see architecture.md. For test conventions and coverage expectations, see testing.md.
- Go 1.25+
- Docker and Docker Compose
- Make
pre-commit(install viabrew install pre-commit, thenpre-commit install)
| Command | Description |
|---|---|
make up |
Build the local signer-dev image. Start LocalStack. |
make down |
Tear down the local environment: stop the app (via app.pid) and run docker-compose down --remove-orphans |
make dev |
make up + launch the app (typical dev entry point) |
The development settings use separate provider switches:
APP_PROVIDER_SECRETS_LOCALSTACK_ENABLEDselects LocalStack for Secrets Manager.APP_PROVIDER_AWSKMS_LOCALSTACK_ENABLEDselects LocalStack for KMS.
The signer-dev image can use standard AWS KMS while APP_ENV=dev. Set
APP_PROVIDER_AWSKMS_LOCALSTACK_ENABLED=false and provide
APP_PROVIDER_AWSKMS_ARNS and AWS credentials. The development compose stack
still starts LocalStack, but the KMS proxy does not use it. Standard AWS KMS in
non-Nitro mode does not send enclave attestation.
| Command | Description |
|---|---|
make proto |
Regenerate protocol buffer Go code |
make build |
Generate protos and build binary to ./bin/app |
See testing.md for the full test matrix and conventions. Top-level entry points:
| Command | Scope |
|---|---|
make test |
Unit + lint |
make test-it |
Unit + integration (starts localstack) |
make smoke |
Smoke tests against a running service |
make test-all |
All of the above |
- Go version: 1.25
- Copyright header: All
.gofiles except generated*_mock.gofiles must carry the Circle Internet Group Apache 2.0 license header. The exception matches thecheck-copyright-golangpre-commit hook. - Commit messages:
type(ticket|NOSTORY): description, following Conventional Commits for thetypesemantics. Valid tickets follow the project's Jira prefix. - Mocking:
github.com/golang/mock(v1.6.0). Mocks are*_mock.gofiles co-located with the interfaces they mock; regenerate withmockgen. - Config: Viper-based, env var prefix
APP_. See architecture.md#common-production-settings. - Logging: Use the repo-local logger in
internal/common/logging/. - Protocol Buffers: Managed by
buf(config version v2), definitions inproto/. Runmake protoafter editing. - gRPC: Shared foundation in
internal/common/grpc/with standardized client/server lifecycle and error normalization.
Enforced via .pre-commit-config.yaml:
go-fmt,golangci-lint,go-mod-tidy,go-unit-testsno-go-testing— scans files namedtest_*.gofor the literaltesting.T; it does not parse imports, enforce Testify assertion style, or match the repository's standard*_test.gofilenamescheck-copyright-golang— Circle copyright header on.gofiles except generated*_mock.goterraform_fmt— fordeploy/configs
Run pre-commit install once after cloning to enable the hooks locally.
make build— confirm the binary compiles (includes proto generation)make test— unit tests + lint for code changesmake test-it— when changes touch provider integrations, gRPC behavior, enclave communication, or configmake test-all— for high-risk or release-critical changes
Signing-critical and signer-image changes also rely on the CI-only smoke_eif
job, which has no equivalent local make target. See
CI-only EIF Image Validation.
.
├── cmd/ # CLI entry points (app, run-vsockproxy)
├── internal/
│ ├── app/ # Host application (app run)
│ │ ├── public/ # gRPC handlers
│ │ ├── service/ # Business logic (signer)
│ │ ├── provider/ # Secrets Manager + enclave client (no KMS on the host)
│ │ └── metrics/ # API metrics
│ ├── enclave/ # Enclave-side (inside Nitro Enclave)
│ │ ├── public/ # Enclave gRPC handlers
│ │ ├── service/ # Enclave business logic
│ │ ├── provider/ # awskms (KMS client), awsproxy, enclave (NSM)
│ │ └── common/crypto/ # In-enclave AES, BLS, Ed25519 primitives
│ ├── vsockproxy/ # Host-side vsock↔AWS KMS bridge (app run-vsockproxy)
│ ├── common/ # Shared infrastructure
│ │ ├── byteproxy/ # vsock byte proxy + AWS route framing
│ │ ├── config/ # Viper config loader
│ │ ├── crypto/ # AES, random generation
│ │ ├── grpc/ # gRPC client/server/interceptors
│ │ ├── lifecycle/ # Runnable lifecycle management
│ │ ├── logging/ # Structured logging
│ │ ├── metric/ # Datadog metrics
│ │ └── telemetry/ # OpenTelemetry
│ └── smoke/ # End-to-end smoke tests
├── proto/ # Protocol buffers
│ ├── arc/signer/v1/ # SignerService (external API)
│ └── arc/enclave/v1/ # EnclaveService (internal API)
├── docker/ # Docker build configuration
├── deploy/ # Terraform deployment configs
├── deployments/ # Docker Compose (localstack)
└── scripts/ # Build and utility scripts