Skip to content

feat: session-key auth, auth login/status, and config profiles (#13) - #32

Merged
JacobPEvans-personal merged 6 commits into
feat/phase-8-health-depthfrom
feat/phase-9-auth-profiles
Jun 23, 2026
Merged

feat: session-key auth, auth login/status, and config profiles (#13)#32
JacobPEvans-personal merged 6 commits into
feat/phase-8-health-depthfrom
feat/phase-9-auth-profiles

Conversation

@JacobPEvans-personal

Copy link
Copy Markdown
Contributor

Summary

Adds session-key authentication, auth commands, and config-file profiles —
without changing the default token path. Stacked on #31.

What landed

  • Session-key auth — the client sends Authorization: Splunk <sessionKey> when
    SPLUNK_SESSION_KEY is set; SPLUNK_TOKEN still maps to Bearer and takes
    precedence. One new ClientConfig.auth_scheme field; existing behavior is
    byte-for-byte unchanged.
  • splunk auth login — mints a session key via /services/auth/login
    (username from --username/$SPLUNK_USERNAME, password from $SPLUNK_PASSWORD
    or a no-echo prompt — never a flag), prints it, and does not persist the
    secret. splunk auth status reports the active scheme + target without
    revealing the secret.
  • Config profiles — a stdlib-configparser INI ($VCT_SPLUNK_CONFIG, else
    $XDG_CONFIG_HOME/vct-splunk/config). --profile / $SPLUNK_PROFILE selects a
    [section] supplying url / token / session_key / app / owner.
    Precedence: flag > env > profile > default, per value. No new dependency.

Backward compatibility

With no config file, load_profile returns {} and nothing changes — confirmed by
the unchanged existing client tests. Profiles only fill gaps the flag and env leave.

Testing

ruff, pyright (0 errors), pytest (113 passed, 3 integration skipped) green.
New tests: the Splunk auth header, config_from_env token-vs-session precedence,
profile-fills-when-env-unset and env-wins-over-profile, auth login session-key
parse (no Authorization header on the login POST), and auth status.

Stacked on #31 — review against the feat/phase-8-health-depth base.

Closes #13

- The client now supports `Authorization: Splunk <sessionKey>` alongside Bearer
  tokens. config_from_env: SPLUNK_TOKEN -> Bearer (unchanged); else
  SPLUNK_SESSION_KEY -> the Splunk scheme.
- `splunk auth login` mints a session key via /services/auth/login (username +
  password from env or a no-echo prompt, never a flag) and prints it; `auth status`
  reports the active scheme and target without revealing the secret.
- Config-file profiles (stdlib INI): `--profile` / SPLUNK_PROFILE selects a
  [section] supplying url / token / session_key / app / owner. Precedence is
  flag > env > profile > default, applied per value. With no config file there is
  no change -- fully backward compatible.

Closes #13
JacobPEvans-personal added a commit that referenced this pull request Jun 23, 2026
## What

Splunk's REST API accepts two Authorization schemes: `Bearer <JWT>` and
`Splunk <sessionKey>`. The client now supports **both**, picked by env
var:

- `SPLUNK_TOKEN` → `Authorization: Bearer <token>` (default, primary
path — unchanged)
- `SPLUNK_SESSION_KEY` → `Authorization: Splunk <key>`

A session key comes directly from `POST /services/auth/login`, so it
needs no
token-auth enablement and no JWT minting.

## Why

The CI integration job had a long, fragile `mint-token.sh` (enable token
auth →
mint a JWT → parse it, which broke with an opaque `JSONDecodeError`).
That whole
dance is unnecessary: a session key is a single login call. This PR
replaces
`mint-token.sh` with a short `get-session-key.sh` and points the
integration job
at `SPLUNK_SESSION_KEY`.

## Auth posture (intentional)

Username/password is **not** promoted: no `auth login` command is added,
and the
docs keep the JWT/token as the primary path with only a one-clause
mention of
`SPLUNK_SESSION_KEY`. The password only appears inside the CI login
script, which
is internal.

## Scope / safety

- Additive only — the Bearer path and the `{data, meta}` contract are
unchanged.
- The credential still lives only in a request header and is never
logged.
- The integration job stays manual-only (`workflow_dispatch`) and
timeout-capped;
  this PR only swaps how it obtains a credential.

## Tests

`tests/unit/test_session_key_auth.py`: with only `SPLUNK_SESSION_KEY`
set, the
client sends `Authorization: Splunk <key>`; the existing Bearer test
still passes.
Gate (via `.venv/bin`): ruff/pyright clean; `73 passed, 1 skipped`.

> Branched off fresh `origin/main`. Note: phase-9 (#32) later adds a
richer
> session-login + profiles layer on top of this same client seam; I'll
reconcile
> it to this when it merges.
@JacobPEvans-personal
JacobPEvans-personal merged commit 41643d6 into feat/phase-8-health-depth Jun 23, 2026
3 checks passed
@JacobPEvans-personal
JacobPEvans-personal deleted the feat/phase-9-auth-profiles branch June 23, 2026 21:15
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