feat(config): add standalone and O11y deployment authentication#80
Conversation
fercor-cisco
left a comment
There was a problem hiding this comment.
🤖 This review was generated by the Astra agent (claude-opus-4-8). It may contain mistakes.
Verdict: needs_discussion — CRUD auth path is solid and well-tested, but the OTLP export path—the PR's stated purpose—is not wired for O11y and would crash; scope needs confirmation.
General Comments
- 🟠 major (question): The PR summary frames this as "the configuration and authentication foundation needed for the SDK's OTLP transition," and adds
O11yConfig.otlp_endpoint, but the actual trace-export path is not wired for O11y and will crash for any O11y user who exports spans.
SplunkAOOTLPExporter.__init__ (src/splunk_ao/otel.py:119-145) unconditionally does:
api_key = config.api_key.get_secret_value() if config.api_key else Nonethenif not api_key: raise ValueError("API key is required."). For O11y,set_jwt_tokennulls the tokens and noapi_keyis ever set, soconfig.api_keyisNone→ this raises.- Builds the endpoint from
config.api_url(which for O11y ishttps://api.{realm}.../v2/ao) +otel/tracesand sends aSplunk-AO-API-Keyheader — neither matches the realm-derived ingest endpoint (https://ingest.{realm}.../v2/trace/otlp) or theX-SF-Tokenscheme this PR introduces.
Meanwhile O11yConfig.otlp_endpoint (the correct ingest URL) is defined but never consumed anywhere in src/. Is trace export for O11y intended as a follow-up PR? If so, that's fine, but please confirm — as it stands the SDK's core tracing function is broken for O11y even though the config/detection succeeds. If it is a follow-up, a tracking ticket reference in the code or PR would help.
Follow-ups
Suggested follow-up work that could be tracked as Shortcut stories:
src/splunk_ao/deployment.py:104-136:StandaloneConfigand bothotlp_endpointproperties (O11y and standalone) are unused insrc/— only exercised by tests. Once the OTLP export path is wired up they'll have a consumer; until then they're dead code. Additionally,StandaloneConfig.otlp_endpointderives the api host via.replace("://console.", ...).replace("://app.", ...), which silently does nothing for custom console domains (e.g.https://galileo.mycorp.com) and diverges from galileo-core's ownset_api_url, which replacesconsole→apianywhere in the string. Worth reconciling these two derivations when the exporter starts using them.
| if os.environ.get("SPLUNK_AO_SF_TOKEN") or os.environ.get("SPLUNK_AO_SF_API_TOKEN"): | ||
| return None |
There was a problem hiding this comment.
🟡 minor (design): The O11y auth guard passes when either SPLUNK_AO_SF_TOKEN or SPLUNK_AO_SF_API_TOKEN is present, and resolve_deployment() likewise treats SPLUNK_AO_SF_API_TOKEN alone as O11y — but O11yConfig.from_env() (deployment.py:63-78) requires both SPLUNK_AO_REALM and SPLUNK_AO_SF_TOKEN. This creates two configs that clear the auth guard and deployment detection but then fail during construction:
SPLUNK_AO_SF_API_TOKENonly (no realm, no SF_TOKEN) → guard returns None, detection returns O11Y, then_bridge_env_vars→O11yConfig.from_env()raisesMissingConfigurationError.SPLUNK_AO_REALM+SPLUNK_AO_SF_API_TOKENbut noSPLUNK_AO_SF_TOKEN→ a user who only has an API token (sufficient for CRUD, sincecrud_tokenprefers the API token) still cannot construct the config because the ingestSF_TOKENis mandated.
The resulting error is actionable (it names the missing vars), so this isn't a silent failure, but the three layers disagree on what constitutes a valid O11y config. Consider aligning them — e.g. require SPLUNK_AO_REALM in the auth guard, and decide whether SF_TOKEN should truly be mandatory when a CRUD-only API token is supplied.
🤖 Generated by the Astra agent
There was a problem hiding this comment.
Good catch. Changed configuration layers so SPLUNK_AO_REALM plus either token is valid. SPLUNK_AO_SF_API_TOKEN alone with a realm now supports CRUD only use, OTLP exporter construction separately requires SPLUNK_AO_SF_TOKEN and raises an actionable error if it is absent. An API token
without a realm still fails because the realm is required to derive the
CRUD endpoint. Added additional tests.
This is expected follow up work. This PR is limited to deployment detection and CRUD authentication it does not complete O11y trace export. The existing |
6138a77 to
beb6d4c
Compare
Does PR #80 implement Option 3 (Auto-Detection with Strict Validation)?Verdict: Mostly implemented, with two intentional deviations and one piece of dead code. The core of Option 3 — auto-detection via presence of o11y-specific vs. standalone-specific variables, with ambiguity and missing-config rejection — is implemented in Rule-by-rule mapping
The three things worth attention1. o11y no longer strictly requires 2. Standalone detection is broader than spec; standalone validation is looser than spec.
3. Bottom lineThe PR faithfully implements the auto-detection + ambiguity + missing-config heart of Option 3, and is more robust than the spec on ambiguity detection. It diverges on two "require" clauses: o11y no longer mandates 🤖 Analysis generated with Claude Code |
| return self.sf_token | ||
| raise MissingConfigurationError("O11y CRUD requires SPLUNK_AO_SF_API_TOKEN or SPLUNK_AO_SF_TOKEN to be set.") | ||
|
|
||
| def require_ingest_token(self) -> SecretStr: |
There was a problem hiding this comment.
This method is tested but never called by the OTLP export path.
|
Follow-up summary (post-merge)Consolidating the outcome of the review discussion so the follow-up scope is clear before merge. Tracked in Jira
Decisions made in review (no further action)
Scope of this PRDeployment detection + CRUD authentication only. Standalone behavior is unchanged; O11y CRUD is complete. O11y trace/log export is intentionally deferred to the tickets above. |
fercor-cisco
left a comment
There was a problem hiding this comment.
See comment above about follow-ups.
Summary
Add configuration detection for standalone and O11y deployments. This establishes the configuration and authentication foundation needed for the SDK's OTLP transition while preserving the existing standalone authentication flow.
Why
The SDK must select the correct endpoints and authentication mechanism without requiring users to set an explicit deployment-mode option. Standalone customers continue using their existing configuration, while O11y customers configure a realm and Splunk access token and do not perform the standalone JWT exchange.
What changed
X-SF-Tokenand consistently applies the/v2/aoprefix to synchronous, asynchronous, and streaming requests.SPLUNK_AO_SF_API_TOKENfor CRUD when provided and otherwise useSPLUNK_AO_SF_TOKEN.httpxas a direct dependency because it is imported by the SDK.Configuration
SPLUNK_AO_REALM,SPLUNK_AO_SF_TOKENSPLUNK_AO_SF_API_TOKENSPLUNK_AO_API_KEY,SPLUNK_AO_CONSOLE_URLSPLUNK_AO_API_URLTesting
HOME=/private/tmp/splunk-ao-pr1-test-home poetry run pytest -q— 125 passed; Ruff lint and format checks, mypy, andgit diff --checkalso passed.