Skip to content

feat: add CLI and HTTP server scaffolding#4

Merged
alanshaw merged 8 commits into
ash/feat/upload-service-clientfrom
ash/feat/cli-and-http-server-scaffolding
Jul 2, 2026
Merged

feat: add CLI and HTTP server scaffolding#4
alanshaw merged 8 commits into
ash/feat/upload-service-clientfrom
ash/feat/cli-and-http-server-scaffolding

Conversation

@alanshaw

@alanshaw alanshaw commented Jun 24, 2026

Copy link
Copy Markdown
Member

Adds scaffolding for the CLI - a hilt serve command that currently starts a HTTP server that prints "Hello World". Server is configured via cbora flags and viper config.

Depends on:

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds initial scaffolding for running hilt as a service: a Cobra-based hilt serve command that loads config via Viper and starts an Echo HTTP server wired together with Uber Fx.

Changes:

  • Introduce Fx modules for config surfacing, zap logging, and Echo server lifecycle management.
  • Add Viper-based config loading with defaults, env var support, and pflag binding.
  • Add cmd/main.go CLI entrypoint plus basic Makefile/.gitignore and new dependencies (Echo, Cobra, Viper, Fx).

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pkg/fx/server.go New Echo server wiring + fx lifecycle hooks for start/stop
pkg/fx/logger.go New zap logger provider and fx event logger configuration
pkg/fx/config.go Exposes config subsections into the fx graph via fx.Out
pkg/fx/app.go Aggregates application fx modules and supplies loaded config
pkg/echo/middleware/logger.go Adds Echo request logging middleware backed by zap
pkg/config/config.go Adds Viper config loading (defaults/env/config file/flags)
cmd/main.go Adds Cobra CLI (hilt serve) that loads config and runs fx app
Makefile Adds basic build/test/vet/clean targets
.gitignore Ignores locally built hilt binary
go.mod Adds dependencies for Echo/Cobra/Viper/Fx (and indirect deps)
go.sum Records checksums for newly added dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/config/config.go
Comment thread cmd/main.go Outdated
Comment thread cmd/main.go
Comment thread pkg/fx/logger.go Outdated
Comment thread pkg/fx/server.go
Comment thread pkg/fx/server.go
Comment thread Makefile Outdated
Comment thread pkg/config/config.go
Comment thread cmd/main.go Outdated
alanshaw and others added 3 commits June 24, 2026 11:24
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread pkg/fx/server.go
alanshaw and others added 2 commits June 25, 2026 09:55
Co-authored-by: Adrian Lanzafame <adrianlanzafame92@gmail.com>
Comment thread pkg/fx/server.go Outdated
},
OnStop: func(ctx context.Context) error {
logger.Info("shutting down server")
shutdownCtx, cancel := context.WithTimeout(ctx, 10*time.Second)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context passed on OnStop from fx already has a timeout, which could be less than this value. Preference is to set the gloabl shutdown timeout on fx once and assume it everywhere, dropping these internal timeout calls.

alanshaw and others added 2 commits July 2, 2026 09:58
) (#12)

Adds initial Tenant + Access Key management API scaffolding and wires store backends (memory/postgres) into the Fx app based on configuration, including new config types/flags and Postgres migration hooks.

**Changes:**
- Introduces API route stubs and request/response types for tenant + access key endpoints, and auto-registers routes onto the Echo server via an Fx group.
- Adds storage backend selection (memory vs postgres) in `AppModule`, plus Fx modules to provide the corresponding store implementations.
- Expands configuration to include `storage.*` and `storage.postgres.*` settings and flag bindings; standardizes PG unique-violation handling using `pgerrcode`.

---

Adds a configurable “partner key” authentication mechanism to gate access to the Tenant API routes, wiring the key through config/flags and enforcing it via Echo middleware.

**Changes:**
- Introduces `AuthConfig` (`auth.partner_key`) and exposes it through the fx config module.
- Wraps all Tenant API routes in partner-key bearer auth middleware while keeping `/` and `/health` open.
- Adds new Echo middleware + unit tests for partner-key bearer authentication.

---

Adds a KMS-agnostic `vault.Vault` interface plus in-memory and HashiCorp Vault (KV v2) implementations, and wires vault selection/config into the fx app and CLI so Hilt can persist private key material in a configurable backend.

**Changes:**
- Introduce `pkg/vault.Vault` interface with `ErrNotFound`, plus an in-memory implementation and a HashiCorp Vault (KV v2) implementation (including AppRole auth helper).
- Add config schema + viper defaults + CLI flags for selecting/configuring the vault backend, and wire backend selection into the fx app graph.
- Add tests for the vault interface contract and HashiCorp AppRole login using a testcontainers Vault dev container.

---

Implements tenant provisioning via `PUT /tenants/{tenantId}` by introducing an external tenant identifier, wiring a did:plc directory client, generating/storing tenant keys in Vault, and persisting tenant records.

**Changes:**
- Added `external_id` to tenant storage model and introduced `GetByExternalID` for idempotent provisioning.
- Added PLC directory configuration + fx wiring to provide a `plc.DirectoryClient`.
- Implemented `ProvisionTenant` API handler with accompanying tests (memory stores + httptest PLC server).

---

Implements the remaining tenant management endpoints by wiring real store-backed handlers and adding the store capabilities required to support tenant deletion cascades (buckets, access keys, delegations, vault secrets, and did:plc deactivation).

**Changes:**
- Implement `GET /tenants/:tenantId`, `POST /tenants/:tenantId/status`, and `DELETE /tenants/:tenantId` handlers (with did:plc deactivation + cascade cleanup).
- Extend tenant/bucket/access-key stores with `Delete` and “list by tenant” capabilities, including pagination for buckets.
- Add/extend unit tests for the new store methods and HTTP handlers; bump dependencies to newer `ucantone` and `dag-json-gen`.

---

This PR implements the Management API access-key endpoints, including key material storage in Vault and issuing tenant→access-key UCAN delegations based on requested S3 permissions. It also extends the store layer to support access-key expiry and efficient bucket lookups by ID for response rendering.

**Changes:**
- Implement Create/List/Get/Delete access-key handlers, including Vault secret storage and delegation issuance/revocation.
- Add `expires_at` support for access keys across schema, store implementations, and tests.
- Extend bucket listing to support filtering by explicit bucket IDs via new `bucket.ListOption`/`bucket.ListConfig`.

---

Adds initial scaffolding for Hilt’s UCAN-based RPC surface (used by Ingot for S3 tenant management), including an identity-backed UCAN server mounted on the existing Echo HTTP server.

**Changes:**
- Introduces UCAN RPC handler stubs and wires them into an `fx` module that builds a `ucantone` HTTP server.
- Adds a configurable service identity (PEM-backed or ephemeral) and exposes a public `did:web` DID document endpoint.
- Extends configuration/CLI flags to support identity settings.
@alanshaw alanshaw merged commit 993ca69 into ash/feat/upload-service-client Jul 2, 2026
4 checks passed
alanshaw added a commit that referenced this pull request Jul 2, 2026
) (#12)

Adds a new Go client for interacting with the upload service via UCAN RPC invocations, along with structured logging helpers to make invocation arguments/metadata easier to inspect in logs.

**Changes:**
- Introduce `pkg/client.UploadClient` with `RegisterCustomer` (`/customer/add`) and `ProvisionSpace` (`/provider/add`) operations.
- Add `pkg/lib/zapucan` helpers for logging UCAN invocations and decoding CBOR-encoded IPLD maps into zap fields.
- Bump `github.com/fil-forge/libforge` dependency version.

---

Adds initial scaffolding for running hilt as a service: a Cobra-based `hilt serve` command that loads config via Viper and starts an Echo HTTP server wired together with Uber Fx.

**Changes:**
- Introduce Fx modules for config surfacing, zap logging, and Echo server lifecycle management.
- Add Viper-based config loading with defaults, env var support, and pflag binding.
- Add `cmd/main.go` CLI entrypoint plus basic Makefile/.gitignore and new dependencies (Echo, Cobra, Viper, Fx).

---

Adds initial Tenant + Access Key management API scaffolding and wires store backends (memory/postgres) into the Fx app based on configuration, including new config types/flags and Postgres migration hooks.

**Changes:**
- Introduces API route stubs and request/response types for tenant + access key endpoints, and auto-registers routes onto the Echo server via an Fx group.
- Adds storage backend selection (memory vs postgres) in `AppModule`, plus Fx modules to provide the corresponding store implementations.
- Expands configuration to include `storage.*` and `storage.postgres.*` settings and flag bindings; standardizes PG unique-violation handling using `pgerrcode`.

---

Adds a configurable “partner key” authentication mechanism to gate access to the Tenant API routes, wiring the key through config/flags and enforcing it via Echo middleware.

**Changes:**
- Introduces `AuthConfig` (`auth.partner_key`) and exposes it through the fx config module.
- Wraps all Tenant API routes in partner-key bearer auth middleware while keeping `/` and `/health` open.
- Adds new Echo middleware + unit tests for partner-key bearer authentication.

---

Adds a KMS-agnostic `vault.Vault` interface plus in-memory and HashiCorp Vault (KV v2) implementations, and wires vault selection/config into the fx app and CLI so Hilt can persist private key material in a configurable backend.

**Changes:**
- Introduce `pkg/vault.Vault` interface with `ErrNotFound`, plus an in-memory implementation and a HashiCorp Vault (KV v2) implementation (including AppRole auth helper).
- Add config schema + viper defaults + CLI flags for selecting/configuring the vault backend, and wire backend selection into the fx app graph.
- Add tests for the vault interface contract and HashiCorp AppRole login using a testcontainers Vault dev container.

---

Implements tenant provisioning via `PUT /tenants/{tenantId}` by introducing an external tenant identifier, wiring a did:plc directory client, generating/storing tenant keys in Vault, and persisting tenant records.

**Changes:**
- Added `external_id` to tenant storage model and introduced `GetByExternalID` for idempotent provisioning.
- Added PLC directory configuration + fx wiring to provide a `plc.DirectoryClient`.
- Implemented `ProvisionTenant` API handler with accompanying tests (memory stores + httptest PLC server).

---

Implements the remaining tenant management endpoints by wiring real store-backed handlers and adding the store capabilities required to support tenant deletion cascades (buckets, access keys, delegations, vault secrets, and did:plc deactivation).

**Changes:**
- Implement `GET /tenants/:tenantId`, `POST /tenants/:tenantId/status`, and `DELETE /tenants/:tenantId` handlers (with did:plc deactivation + cascade cleanup).
- Extend tenant/bucket/access-key stores with `Delete` and “list by tenant” capabilities, including pagination for buckets.
- Add/extend unit tests for the new store methods and HTTP handlers; bump dependencies to newer `ucantone` and `dag-json-gen`.

---

This PR implements the Management API access-key endpoints, including key material storage in Vault and issuing tenant→access-key UCAN delegations based on requested S3 permissions. It also extends the store layer to support access-key expiry and efficient bucket lookups by ID for response rendering.

**Changes:**
- Implement Create/List/Get/Delete access-key handlers, including Vault secret storage and delegation issuance/revocation.
- Add `expires_at` support for access keys across schema, store implementations, and tests.
- Extend bucket listing to support filtering by explicit bucket IDs via new `bucket.ListOption`/`bucket.ListConfig`.

---

Adds initial scaffolding for Hilt’s UCAN-based RPC surface (used by Ingot for S3 tenant management), including an identity-backed UCAN server mounted on the existing Echo HTTP server.

**Changes:**
- Introduces UCAN RPC handler stubs and wires them into an `fx` module that builds a `ucantone` HTTP server.
- Adds a configurable service identity (PEM-backed or ephemeral) and exposes a public `did:web` DID document endpoint.
- Extends configuration/CLI flags to support identity settings.
alanshaw added a commit that referenced this pull request Jul 2, 2026
)

Adds a new Go client for interacting with the upload service via UCAN RPC invocations, along with structured logging helpers to make invocation arguments/metadata easier to inspect in logs.

**Changes:**
- Introduce `pkg/client.UploadClient` with `RegisterCustomer` (`/customer/add`) and `ProvisionSpace` (`/provider/add`) operations.
- Add `pkg/lib/zapucan` helpers for logging UCAN invocations and decoding CBOR-encoded IPLD maps into zap fields.
- Bump `github.com/fil-forge/libforge` dependency version.

---

Adds initial scaffolding for running hilt as a service: a Cobra-based `hilt serve` command that loads config via Viper and starts an Echo HTTP server wired together with Uber Fx.

**Changes:**
- Introduce Fx modules for config surfacing, zap logging, and Echo server lifecycle management.
- Add Viper-based config loading with defaults, env var support, and pflag binding.
- Add `cmd/main.go` CLI entrypoint plus basic Makefile/.gitignore and new dependencies (Echo, Cobra, Viper, Fx).

---

Adds initial Tenant + Access Key management API scaffolding and wires store backends (memory/postgres) into the Fx app based on configuration, including new config types/flags and Postgres migration hooks.

**Changes:**
- Introduces API route stubs and request/response types for tenant + access key endpoints, and auto-registers routes onto the Echo server via an Fx group.
- Adds storage backend selection (memory vs postgres) in `AppModule`, plus Fx modules to provide the corresponding store implementations.
- Expands configuration to include `storage.*` and `storage.postgres.*` settings and flag bindings; standardizes PG unique-violation handling using `pgerrcode`.

---

Adds a configurable “partner key” authentication mechanism to gate access to the Tenant API routes, wiring the key through config/flags and enforcing it via Echo middleware.

**Changes:**
- Introduces `AuthConfig` (`auth.partner_key`) and exposes it through the fx config module.
- Wraps all Tenant API routes in partner-key bearer auth middleware while keeping `/` and `/health` open.
- Adds new Echo middleware + unit tests for partner-key bearer authentication.

---

Adds a KMS-agnostic `vault.Vault` interface plus in-memory and HashiCorp Vault (KV v2) implementations, and wires vault selection/config into the fx app and CLI so Hilt can persist private key material in a configurable backend.

**Changes:**
- Introduce `pkg/vault.Vault` interface with `ErrNotFound`, plus an in-memory implementation and a HashiCorp Vault (KV v2) implementation (including AppRole auth helper).
- Add config schema + viper defaults + CLI flags for selecting/configuring the vault backend, and wire backend selection into the fx app graph.
- Add tests for the vault interface contract and HashiCorp AppRole login using a testcontainers Vault dev container.

---

Implements tenant provisioning via `PUT /tenants/{tenantId}` by introducing an external tenant identifier, wiring a did:plc directory client, generating/storing tenant keys in Vault, and persisting tenant records.

**Changes:**
- Added `external_id` to tenant storage model and introduced `GetByExternalID` for idempotent provisioning.
- Added PLC directory configuration + fx wiring to provide a `plc.DirectoryClient`.
- Implemented `ProvisionTenant` API handler with accompanying tests (memory stores + httptest PLC server).

---

Implements the remaining tenant management endpoints by wiring real store-backed handlers and adding the store capabilities required to support tenant deletion cascades (buckets, access keys, delegations, vault secrets, and did:plc deactivation).

**Changes:**
- Implement `GET /tenants/:tenantId`, `POST /tenants/:tenantId/status`, and `DELETE /tenants/:tenantId` handlers (with did:plc deactivation + cascade cleanup).
- Extend tenant/bucket/access-key stores with `Delete` and “list by tenant” capabilities, including pagination for buckets.
- Add/extend unit tests for the new store methods and HTTP handlers; bump dependencies to newer `ucantone` and `dag-json-gen`.

---

This PR implements the Management API access-key endpoints, including key material storage in Vault and issuing tenant→access-key UCAN delegations based on requested S3 permissions. It also extends the store layer to support access-key expiry and efficient bucket lookups by ID for response rendering.

**Changes:**
- Implement Create/List/Get/Delete access-key handlers, including Vault secret storage and delegation issuance/revocation.
- Add `expires_at` support for access keys across schema, store implementations, and tests.
- Extend bucket listing to support filtering by explicit bucket IDs via new `bucket.ListOption`/`bucket.ListConfig`.

---

Adds initial scaffolding for Hilt’s UCAN-based RPC surface (used by Ingot for S3 tenant management), including an identity-backed UCAN server mounted on the existing Echo HTTP server.

**Changes:**
- Introduces UCAN RPC handler stubs and wires them into an `fx` module that builds a `ucantone` HTTP server.
- Adds a configurable service identity (PEM-backed or ephemeral) and exposes a public `did:web` DID document endpoint.
- Extends configuration/CLI flags to support identity settings.
alanshaw added a commit that referenced this pull request Jul 2, 2026
) (#8) (#9) (#10) (#11) (#12)

This PR introduces a new `pkg/store` layer with both in-memory and Postgres-backed implementations for core entities (provider, tenant, bucket, access key, delegation), plus embedded goose migrations and test utilities to run Postgres-backed store tests via testcontainers.

**Changes:**
- Add store interfaces + in-memory and Postgres implementations for provider/tenant/bucket/accesskey/delegation.
- Add embedded goose migrations and a migrations runner to initialize Postgres schema.
- Add test utilities and cross-implementation tests (memory + Postgres) for each store.

---

Adds a new Go client for interacting with the upload service via UCAN RPC invocations, along with structured logging helpers to make invocation arguments/metadata easier to inspect in logs.

**Changes:**
- Introduce `pkg/client.UploadClient` with `RegisterCustomer` (`/customer/add`) and `ProvisionSpace` (`/provider/add`) operations.
- Add `pkg/lib/zapucan` helpers for logging UCAN invocations and decoding CBOR-encoded IPLD maps into zap fields.
- Bump `github.com/fil-forge/libforge` dependency version.

---

Adds initial scaffolding for running hilt as a service: a Cobra-based `hilt serve` command that loads config via Viper and starts an Echo HTTP server wired together with Uber Fx.

**Changes:**
- Introduce Fx modules for config surfacing, zap logging, and Echo server lifecycle management.
- Add Viper-based config loading with defaults, env var support, and pflag binding.
- Add `cmd/main.go` CLI entrypoint plus basic Makefile/.gitignore and new dependencies (Echo, Cobra, Viper, Fx).

---

Adds initial Tenant + Access Key management API scaffolding and wires store backends (memory/postgres) into the Fx app based on configuration, including new config types/flags and Postgres migration hooks.

**Changes:**
- Introduces API route stubs and request/response types for tenant + access key endpoints, and auto-registers routes onto the Echo server via an Fx group.
- Adds storage backend selection (memory vs postgres) in `AppModule`, plus Fx modules to provide the corresponding store implementations.
- Expands configuration to include `storage.*` and `storage.postgres.*` settings and flag bindings; standardizes PG unique-violation handling using `pgerrcode`.

---

Adds a configurable “partner key” authentication mechanism to gate access to the Tenant API routes, wiring the key through config/flags and enforcing it via Echo middleware.

**Changes:**
- Introduces `AuthConfig` (`auth.partner_key`) and exposes it through the fx config module.
- Wraps all Tenant API routes in partner-key bearer auth middleware while keeping `/` and `/health` open.
- Adds new Echo middleware + unit tests for partner-key bearer authentication.

---

Adds a KMS-agnostic `vault.Vault` interface plus in-memory and HashiCorp Vault (KV v2) implementations, and wires vault selection/config into the fx app and CLI so Hilt can persist private key material in a configurable backend.

**Changes:**
- Introduce `pkg/vault.Vault` interface with `ErrNotFound`, plus an in-memory implementation and a HashiCorp Vault (KV v2) implementation (including AppRole auth helper).
- Add config schema + viper defaults + CLI flags for selecting/configuring the vault backend, and wire backend selection into the fx app graph.
- Add tests for the vault interface contract and HashiCorp AppRole login using a testcontainers Vault dev container.

---

Implements tenant provisioning via `PUT /tenants/{tenantId}` by introducing an external tenant identifier, wiring a did:plc directory client, generating/storing tenant keys in Vault, and persisting tenant records.

**Changes:**
- Added `external_id` to tenant storage model and introduced `GetByExternalID` for idempotent provisioning.
- Added PLC directory configuration + fx wiring to provide a `plc.DirectoryClient`.
- Implemented `ProvisionTenant` API handler with accompanying tests (memory stores + httptest PLC server).

---

Implements the remaining tenant management endpoints by wiring real store-backed handlers and adding the store capabilities required to support tenant deletion cascades (buckets, access keys, delegations, vault secrets, and did:plc deactivation).

**Changes:**
- Implement `GET /tenants/:tenantId`, `POST /tenants/:tenantId/status`, and `DELETE /tenants/:tenantId` handlers (with did:plc deactivation + cascade cleanup).
- Extend tenant/bucket/access-key stores with `Delete` and “list by tenant” capabilities, including pagination for buckets.
- Add/extend unit tests for the new store methods and HTTP handlers; bump dependencies to newer `ucantone` and `dag-json-gen`.

---

This PR implements the Management API access-key endpoints, including key material storage in Vault and issuing tenant→access-key UCAN delegations based on requested S3 permissions. It also extends the store layer to support access-key expiry and efficient bucket lookups by ID for response rendering.

**Changes:**
- Implement Create/List/Get/Delete access-key handlers, including Vault secret storage and delegation issuance/revocation.
- Add `expires_at` support for access keys across schema, store implementations, and tests.
- Extend bucket listing to support filtering by explicit bucket IDs via new `bucket.ListOption`/`bucket.ListConfig`.

---

Adds initial scaffolding for Hilt’s UCAN-based RPC surface (used by Ingot for S3 tenant management), including an identity-backed UCAN server mounted on the existing Echo HTTP server.

**Changes:**
- Introduces UCAN RPC handler stubs and wires them into an `fx` module that builds a `ucantone` HTTP server.
- Adds a configurable service identity (PEM-backed or ephemeral) and exposes a public `did:web` DID document endpoint.
- Extends configuration/CLI flags to support identity settings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants