Skip to content

feat: secret support — hm.secrets["…"], local .env resolution, hm cloud secret CLI#152

Open
markovejnovic wants to merge 11 commits into
mainfrom
cli-41-secrets
Open

feat: secret support — hm.secrets["…"], local .env resolution, hm cloud secret CLI#152
markovejnovic wants to merge 11 commits into
mainfrom
cli-41-secrets

Conversation

@markovejnovic

@markovejnovic markovejnovic commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

No description provided.

markovejnovic and others added 11 commits June 17, 2026 15:27
Drop all TS DSL artifacts (harmont-ts/, ts_engine, build.rs,
TS init templates, example pipeline.ts files, TS e2e fixtures)
to align with main's TS DSL deletion before merging.
Introduce the hm-core crate as the home for process-level state (Sys) and
project-level state (Workspace), and move credential storage into it.

The credential store collapses from a two-level (service, account) map to a
single token. The cloud issues one user-scoped bearer -- claim_token /
redeem_code take no org, and that one token lists every organization the
user belongs to -- so keying it by anything was storing one secret under a
key that could not discriminate it. A second API base (localhost, staging)
is served by HM_API_TOKEN, which is how the integration tests already inject
one, so the stored file only ever held a single entry in practice.

This is a breaking change to ~/.config/hm/credentials.toml. The old nested
shape no longer parses and there is no migration; existing logins must
re-run `hm cloud login`.

Behaviour changes beyond the move:

- The file must be owned by the invoking user and chmod 0600, else load
  fails. Previously a malformed or insecure file was silently ignored.
- Tokens are held as secrecy::SecretString rather than String, so they no
  longer leak through Debug. They are exposed only at the two points that
  need a str: HarmontClient::with_base_url and the Authorization header.
- HM_API_TOKEN="" is treated as unset. Honouring it sent an empty bearer
  (a 401) instead of falling back to the stored credential, which bites
  when CI exports an unset secret as the empty string.

Also consolidates the duplicated Workspace. hm-exec/src/domain/workspace.rs
and hm-core/workspace.rs were byte-identical; hm-core now owns the only
definition and hm-exec drops its hm-config dependency in favour of hm-core.

Supporting work: hm-util gains AbsPath/AbsPathBuf and RelPath/RelPathBuf,
typed wrappers that carry the absolute/relative invariant; hm-config drops
its now-unused anyhow dependency and replaces two hand-written Default impls
with SmartDefault.

Includes in-progress secrets-provider scaffolding (hm-exec domain::secrets,
local/cloud providers) that is not yet wired to a call site.
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.

1 participant