AGENTS.md — Global Trust Authority (GTA)

Project Overview

GTA is a secure remote attestation service written in Rust (edition 2021, MSRV 1.82+). It validates the integrity of remote nodes (cloud instances, edge devices) through hardware-verified cryptographic attestation from TPM 2.0 (including IMA and boot quotes), VirtCCA, iTrustee, CCA, Ascend NPU, and DICE sources.

Repository: Part of the openEuler ecosystem. Upstream: gitcode.com/openeuler/global-trust-authority.

Note: Architecture SSOT is docs/zh/architecture.md (English twin: docs/en/architecture.md). Module boundaries, trust boundaries, and design decisions must align with that document; update it when architecture changes.

Workspace Structure

The workspace has 49 crates (46 explicit members in the root Cargo.toml, plus path-dependency crates such as tpm_common_* and common_verifier). Each follows this layout:

crate_name/
├── Cargo.toml          # Deps use `workspace = true` for shared versions
├── src/
│   ├── lib.rs          # Library root (most crates are libs)
│   └── *.rs, mod.rs   # Module organization
└── tests/              # Integration tests

Key bins (entry points)

Binary Workspace path Cargo package Source
attestation_service attestation_server/api attestation_service src/main.rs
attestation_agent attestation_agent/agent attestation_agent src/main.rs
attestation_cli attestation_cli attestation_cli src/main.rs
key_managerd key_manager key_managerd src/main.rs
key_manager (CLI) key_manager key_managerd src/bin/cli/main.rs

Use the Cargo package name with -p / --package (e.g. cargo test -p key_managerd, not key_manager).

Infrastructure crates (attestation_common/)

Crate Purpose
cache Redis caching (attestation_common/cache)
rdb Sea-ORM abstraction (SQLite/MySQL/PostgreSQL)
mq Kafka messaging
distributed_lock Redis-based distributed locks
jwt JWT sign/verify
ratelimit Governor-based rate limiting
schedule_job Cron scheduling
config_manager YAML config loading
env_config_parse Environment variable parsing
common_log log4rs config

Build & Development Commands

# Build workspace (full build requires libqca, tss2, etc. — see scripts/pipeline_code_check.sh)
cargo build --release

# Build a specific package
cargo build --release --package attestation_service

# Build with Docker feature
cargo build --release --package attestation_service --features docker_build

# Lint (project standard)
cargo clippy -- --cap-lints warn -W clippy::all -A clippy::restriction

# Format
cargo fmt

# Run tests (use --package / -p with the Cargo package name)
cargo test --package attestation
cargo test --package challenge
cargo test --package key_managerd

# Run a single test
cargo test --package attestation test_attestation_chain

# Run tests with output
cargo test -- --nocapture

# Docker Compose (service + mysql + redis)
docker compose -f docker/docker-compose.yaml up

# Docker Compose with key manager
docker compose -f docker/docker-compose.yaml --profile keymanager up

Build prerequisites

The full native build needs system libraries: openssl-devel, zlib-devel, cmake, gcc, tpm2-tss-devel, clang, libboundscheck, virtCCA_sdk, virtCCA_sdk-devel, and itrustee_sdk.

Partial builds (e.g., cargo check --package attestation) work with a standard Rust toolchain.

License header

Every .rs file must start with:

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * ...
 */

Imports

  • Use use crate::... for intra-crate references
  • Group imports: std → external crates → workspace crates (separated by blank lines)
  • Prefer explicit imports over glob imports

Error handling

  • Use thiserror for library error types
  • Do not use unwrap() and expect() in production code; propagate errors with Result<T, E> and ?
  • Do not use todo!() or unimplemented!() in production code

Async

  • New or changed IO operations should be async when practical; keep blocking IO out of hot async request paths
  • Use tokio::spawn for concurrent tasks
  • Avoid std::sync::Mutex in async contexts — use parking_lot::Mutex or tokio::sync::Mutex

Naming

  • Crate names: snake_case (e.g., attestation, policy_engine, key_managerd)
  • Module names: snake_case
  • Types/Structs/Enums: UpperCamelCase
  • Functions/Methods: snake_case
  • Constants: UPPER_SNAKE_CASE

Testing

Test organization

  • Integration tests: crate/tests/test_*.rs (some crates use tests/mod.rs to wire modules)
  • Unit tests: #[cfg(test)] mod tests { ... } blocks inline in source files
  • Mock plugins: Separate crate projects (e.g. plugin_manager/tests/mock_plugin_for_service/, attestation_server/attestation/tests/mock_test_attester/)

Testing tools

use serial_test::serial;    // For tests requiring serial execution
use mockall::mock;           // For mocking traits
use actix_web::test;         // For HTTP handler testing
use tempfile::tempdir;       // For temporary files

Test data

  • Test certificates generated by rcgen (workspace dep, test-only)
  • Fixture data in key_manager/tests/testdata/
  • Helper scripts in scripts/ (e.g., generate_test_data.sh)

Writing new tests

  • Add integration tests as tests/test_<feature>.rs in the relevant crate
  • Use serial_test when tests share global state or hardware access (TPM, etc.)
  • Prefer integration tests over unit tests for plugin and workflow logic

Adding a New Attestation Type

When adding support for a new hardware attestation source, create both:

  1. Attester in attestation_agent/attester/<name>/:

    • Build as a dylib and implement AgentPlugin from plugin_manager
    • Follow an existing attester in the same family (e.g. virtcca, tpm/ima); typical modules include lib.rs and attester.rs, with config.rs or entity.rs when needed
    • Add tests in tests/
  2. Verifier in attestation_server/verifier/<name>/:

    • Build as a dylib and implement ServicePlugin from plugin_manager
    • Follow an existing verifier in the same family; typical modules include lib.rs and verifier.rs, with evidence.rs when needed
    • Add tests in tests/
  3. Wire both into agent/server plugin configuration so they are loaded at runtime (dynamic .so loading via load_plugins / PluginManager — do not hardcode plugins outside the plugin system)

Configuration

  • Server: attestation_server/conf/server_config.yaml + .env
  • Agent: attestation_agent/conf/agent_config.yaml
  • Key Manager: key_manager/.env
  • Logging: attestation_server/conf/logging.yaml (log4rs, 10MB rotation)

Configuration is loaded through config_manager + env_config_parse crates. Never hardcode configuration values.

Documentation

  • CONTRIBUTING: /CONTRIBUTING.md — bilingual (Chinese / English) contribution guide: setup, branch prefixes, coding standards, testing, quality gates, MR checklist; in case of divergence, the English version prevails
  • README: /README.md — product intro, build guide, doc links
  • Architecture: docs/zh/architecture.md (SSOT); docs/en/architecture.md (EN)
  • API docs: docs/en/api_documentation.md (EN), docs/zh/api_documentation.md (ZH)
  • Deployment: docs/en/GTA_Usage_Guidelines.md, docs/en/key_manager_install.md
  • Service files: service/ — systemd unit files
  • RPM specs: rpm/spec/ — packaging

Repository Conventions

  • Base branch: master (upstream: origin/master)
  • Feature branches: br_feat_* prefix for release branches, descriptive names for feature work
  • Commit messages: Chinese/English mixed. Use conventional format: feat:, fix:, docs:, refactor:, test:
  • PR merge commits: Format !<PR_NUMBER> <message> (e.g., !315 update dockerfile when key_manager)
  • Run local quality gates (cargo fmt, cargo clippy, affected cargo test) before opening an MR

CI / Quality Gates

The CI pipeline (scripts/pipeline_code_check.sh) installs native build dependencies (libboundscheck, itrustee_sdk, TPM2 libs, etc.) and runs:

cargo clippy -- --cap-lints warn -W clippy::all -A clippy::restriction

(warn-only, not deny). It does not run cargo test or a full cargo build — run tests locally before merge.

Pre-commit expectations:

  • cargo fmt passes
  • cargo clippy produces no new warnings
  • Tests pass for affected crates

Security-Sensitive Areas

  • Key management: All keys go through key_manager → OpenBao/Vault (never stored in plaintext)
  • Nonce handling: Replay attack prevention in attestation_server/nonce and attestation_agent/challenge
  • Certificate verification: AK trust chain validation in attestation_server/endorserment
  • Token signing: EAT/EAR tokens in attestation_server/token — cryptographic signatures mandatory
  • Input validation: All external inputs validated at the boundary (REST API, CLI, agent endpoints)

Report security issues to openeuler-security@openeuler.org per OpenEuler vulnerability reporting guidelines.