Skip to main content

Architecture Overview

Repo Structure

arcan-oss/
├── cmd/
│ └── arcan/
│ ├── main.go # Entry point, version vars, embed directives
│ ├── root.go # Root cobra command, global flags (--debug)
│ ├── cmd_server.go # arcan server (Standalone or Multi-node)
│ ├── cmd_kv.go # arcan kv set/get/list/delete/export/run/encrypt
│ ├── cmd_realm.go # arcan realm list/create/delete
│ ├── cmd_auth.go # arcan login/register/token
│ ├── cmd_policy.go # arcan policy role/binding/explain/apply
│ ├── cmd_audit.go # arcan audit list/export
│ ├── cmd_plugin.go # arcan plugin install/remove/list/update/search
│ ├── cmd_activate.go # arcan activate <key>
│ ├── cmd_masterkey.go # arcan master-key setup/verify/rewrap/generate
│ ├── cmd_doctor.go # arcan doctor (6-step diagnostic)
│ ├── cmd_diag.go # arcan diag (support bundle)
│ ├── client.go # API client helpers, config loading
│ └── helpers.go # Shared CLI helpers (tables, spinners, errors)

├── internal/
│ ├── server/
│ │ └── server.go # HTTP server, chi router, middleware stack
│ │
│ ├── handler/
│ │ ├── kv.go # KV secret CRUD handlers
│ │ ├── realm.go # Realm CRUD handlers
│ │ ├── realm_resolve.go # Realm resolution + auto-create
│ │ ├── auth.go # Auth handlers (register, login, token)
│ │ ├── policy.go # Policy handlers (roles, bindings, explain)
│ │ ├── audit.go # Audit log query handlers
│ │ ├── engine.go # Engine CRUD (generic — delegates to plugin)
│ │ ├── lease.go # Lease request/revoke (delegates to plugin)
│ │ ├── health.go # Health check endpoint
│ │ └── helpers.go # jsonResponse, jsonError, internalError
│ │
│ ├── store/
│ │ ├── store.go # Store interface (composed sub-interfaces)
│ │ ├── migrate.go # Migration runner (embedded SQL)
│ │ ├── sqlite/ # SQLite implementation
│ │ │ ├── sqlite.go # Constructor, connection setup
│ │ │ ├── migrations/ # Embedded .sql migration files
│ │ │ │ ├── 001_initial.sql
│ │ │ │ └── ...
│ │ │ ├── realm.go # RealmStore methods
│ │ │ ├── secret.go # SecretStore methods
│ │ │ ├── auth.go # AuthStore methods
│ │ │ ├── policy.go # PolicyStore methods
│ │ │ ├── audit.go # AuditStore methods
│ │ │ ├── engine.go # EngineStore methods
│ │ │ ├── lease.go # LeaseStore methods
│ │ │ └── plugin_data.go # Generic plugin key-value storage
│ │ └── postgres/ # PostgreSQL implementation (same file structure)
│ │
│ ├── crypto/
│ │ ├── crypto.go # AESEncryptor, NoopEncryptor
│ │ ├── keymanager.go # KeyManager interface, factory, HKDF derivation
│ │ ├── kms_aws.go # AWS KMS envelope encryption
│ │ ├── kms_gcp.go # GCP Cloud KMS
│ │ ├── kms_azure.go # Azure Key Vault
│ │ └── kms_s3.go # S3/MinIO key storage
│ │
│ ├── policy/
│ │ ├── evaluator.go # RBAC evaluator
│ │ └── evaluator_test.go # Mandatory tests for any policy changes
│ │
│ ├── audit/
│ │ ├── dispatcher.go # Event dispatcher (async, fire-and-forget)
│ │ ├── sink_webhook.go # Webhook sink (Splunk HEC, Datadog, Elastic)
│ │ └── sink_syslog.go # Syslog sink (RFC 5424, TCP/UDP)
│ │
│ ├── model/
│ │ └── models.go # All data models (structs, enums, constants)
│ │
│ ├── middleware/
│ │ ├── auth.go # JWT/token validation middleware
│ │ ├── policy.go # RBAC enforcement middleware
│ │ ├── requestid.go # X-Request-Id propagation
│ │ └── logging.go # Request/response structured logging
│ │
│ ├── engine/
│ │ ├── interface.go # Engine interface (what all engines implement)
│ │ ├── descriptor.go # EngineDescriptor, Capability enum
│ │ ├── registry.go # Engine registry (built-in KV + loaded plugins)
│ │ ├── executor.go # Engine executor (renders templates, calls connections)
│ │ ├── shared.go # SanitizeID, GeneratePassword
│ │ └── kv/ # KV engine (the only built-in engine)
│ │ └── kv.go
│ │
│ ├── plugin/
│ │ ├── loader.go # Package loader (.arcanpkg extract, verify, load)
│ │ ├── runtime.go # Sandboxed execution runtime
│ │ ├── hostfn.go # Host functions exposed to plugins (ArcanContext)
│ │ ├── registry.go # Registry client (discover, download, verify)
│ │ ├── signature.go # Ed25519 signature verification
│ │ └── activation.go # Enterprise KMS activation model
│ │
│ └── connection/
│ ├── manager.go # Connection pool manager (SQL, HTTP, custom)
│ ├── sql.go # SQL driver adapter (postgres, mysql, mssql, etc.)
│ └── http.go # HTTP client adapter (AWS, Azure, GCP, REST APIs)

├── sdk/ # Multi-language SDKs (Go first, then TS, Python)
│ ├── go/ # Go SDK — getarcan.dev/sdk
│ │ ├── go.mod
│ │ ├── engine.go # Engine interface for plugin authors
│ │ ├── context.go # ArcanContext (sql, http, store, audit, crypto)
│ │ ├── helpers.go # GeneratePassword, SanitizeID
│ │ ├── pack.go # Package builder (arcan plugin pack)
│ │ └── example/ # Example plugin scaffold
│ │ ├── main.go
│ │ └── README.md
│ ├── typescript/ # TypeScript SDK (Phase 2)
│ └── python/ # Python SDK (Phase 3)

├── migrations/ # Shared migration SQL (embedded at build)
│ ├── sqlite/
│ │ ├── 001_initial.sql
│ │ └── ...
│ └── postgres/
│ ├── 001_initial.sql
│ └── ...

├── go.mod # getarcan.dev/arcan
├── go.sum
├── Makefile
├── Dockerfile
├── LICENSE # Apache 2.0
├── README.md
├── CLAUDE.md # Engineering Constitution
├── CHANGELOG.md
├── SECURITY.md
├── CONTRIBUTING.md
└── .github/
└── workflows/
├── test.yml
├── build.yml
├── release.yml
└── docker.yml

Dependency Direction

cmd/arcan/            → internal/*           (CLI depends on everything)
internal/handler/ → internal/store/ (handlers call store)
internal/handler/ → internal/engine/ (handlers call engine registry)
internal/handler/ → internal/crypto/ (handlers encrypt/decrypt)
internal/handler/ → internal/audit/ (handlers emit audit events)
internal/handler/ → internal/policy/ (handlers check permissions)
internal/server/ → internal/handler/ (server wires handlers to routes)
internal/server/ → internal/middleware/ (server applies middleware)
internal/engine/ → internal/plugin/ (registry loads plugins via loader)
internal/engine/ → internal/connection/ (executor uses connection manager)
internal/plugin/ → internal/engine/ (runtime implements engine interface)
internal/engine/ → internal/model/ (engines use model types)
internal/store/ → internal/model/ (store uses model types)
internal/connection/ → (external drivers) (sql, http — leaf node)

Forbidden Dependencies

  • internal/model/ must NOT import any other internal/ package
  • internal/store/ must NOT import internal/handler/
  • internal/engine/ must NOT import internal/handler/ or internal/store/
  • internal/crypto/ must NOT import internal/store/ or internal/handler/
  • internal/connection/ must NOT import internal/handler/ or internal/store/
  • sdk/ must NOT import any internal/ package (separate module per language)
  • No circular dependencies. Ever.

Interface Ownership

Interfaces are defined by the consumer, not the implementer:

InterfaceDefined inImplemented by
store.Storeinternal/store/store.gosqlite.Store, postgres.Store
engine.Engineinternal/engine/interface.gokv.Engine, plugin.RuntimeAdapter
crypto.Encryptorinternal/crypto/crypto.goAESEncryptor, NoopEncryptor
crypto.KeyManagerinternal/crypto/keymanager.goAWSKMSKeyManager, GCPKMSKeyManager, etc.
audit.Sinkinternal/audit/dispatcher.goWebhookSink, SyslogSink

Narrow Interfaces

Handler functions accept the narrowest interface they need, not the full Store:

// WRONG — handler takes the full Store
func (h *KVHandler) Get(w http.ResponseWriter, r *http.Request) {
h.store.GetSecret(...) // store is store.Store — 60+ methods
}

// RIGHT — handler takes only what it needs
type KVHandler struct {
secrets store.SecretStore // 6 methods
audit audit.Dispatcher
enc crypto.Encryptor
}