Skip to content

fix: reject clientSecret without clientId to prevent wrong-tenant data#122

Merged
saurabhjain1592 merged 1 commit intomainfrom
fix/require-client-id-with-secret
Apr 5, 2026
Merged

fix: reject clientSecret without clientId to prevent wrong-tenant data#122
saurabhjain1592 merged 1 commit intomainfrom
fix/require-client-id-with-secret

Conversation

@saurabhjain1592
Copy link
Copy Markdown
Member

Summary

Reject client_secret/clientSecret when client_id/clientId is not set. Without this check, the SDK silently uses community as the tenant identity, causing all licensed data to be stored under the wrong tenant.

Three valid configurations:

  • Neither set → community mode (clientId=community, no license)
  • clientId only → community mode with custom tenant
  • Both set → licensed mode with explicit tenant

Aligns with getaxonflow/axonflow-enterprise#1492 unified identity model.

Test plan

  • client_secret without client_id throws clear error
  • client_id without client_secret works (community with custom tenant)
  • Both omitted works (community mode)
  • Both set works (licensed mode)

If clientSecret (license key) is set without clientId, the SDK
would silently use 'community' as the tenant identity. All data
would be stored under the wrong tenant, causing data loss on
upgrade when clientId is eventually set correctly.
@saurabhjain1592 saurabhjain1592 merged commit 3d77ad6 into main Apr 5, 2026
9 checks passed
@saurabhjain1592 saurabhjain1592 deleted the fix/require-client-id-with-secret branch April 7, 2026 10:36
saurabhjain1592 added a commit that referenced this pull request Apr 17, 2026
Adds Java SDK half of ADR-043 + ADR-042.

New:
- DecisionExplanation, ExplainPolicy, ExplainRule DTOs in
  com.getaxonflow.sdk.types. Jackson @JsonIgnoreProperties(ignoreUnknown=
  true) for ADR-043 forward-compat with future platform fields.
- AxonFlow.explainDecision(decisionId) + explainDecisionAsync calling
  GET /api/v1/decisions/:id/explain. URL-encodes the decision ID.
  Rejects null/empty with IllegalArgumentException.
- AuditSearchRequest builder gains decisionId/policyName/overrideId;
  new JSON properties serialize only when set via @JsonInclude(NON_NULL).

Version: 5.3.0 -> 5.4.0 (pom.xml).

Tests (8 new, all passing via WireMock):
- explainDecision: null + empty rejection, full payload parse with URL
  assertion, forward-compat with unknown fields.
- searchAuditLogs: new filters serialize when set, absent when unset.
- DTO null-safety: DecisionExplanation policyMatches defaults to empty
  when constructor receives null; ExplainPolicy defaults.

Companion to platform v7.1.0 (axonflow-enterprise PR #1605), Go SDK
v5.4.0 (PR #122), Python v6.4.0 (PR #141), TS v5.4.0 (PR #175).
saurabhjain1592 added a commit that referenced this pull request Apr 18, 2026
Adds Java SDK half of ADR-043 + ADR-042.

New:
- DecisionExplanation, ExplainPolicy, ExplainRule DTOs in
  com.getaxonflow.sdk.types. Jackson @JsonIgnoreProperties(ignoreUnknown=
  true) for ADR-043 forward-compat with future platform fields.
- AxonFlow.explainDecision(decisionId) + explainDecisionAsync calling
  GET /api/v1/decisions/:id/explain. URL-encodes the decision ID.
  Rejects null/empty with IllegalArgumentException.
- AuditSearchRequest builder gains decisionId/policyName/overrideId;
  new JSON properties serialize only when set via @JsonInclude(NON_NULL).

Version: 5.3.0 -> 5.4.0 (pom.xml).

Tests (8 new, all passing via WireMock):
- explainDecision: null + empty rejection, full payload parse with URL
  assertion, forward-compat with unknown fields.
- searchAuditLogs: new filters serialize when set, absent when unset.
- DTO null-safety: DecisionExplanation policyMatches defaults to empty
  when constructor receives null; ExplainPolicy defaults.

Companion to platform v7.1.0 (axonflow-enterprise PR #1605), Go SDK
v5.4.0 (PR #122), Python v6.4.0 (PR #141), TS v5.4.0 (PR #175).
saurabhjain1592 added a commit that referenced this pull request Apr 18, 2026
* feat: explainDecision + audit search filter parity (Plugin Batch 1)

Adds Java SDK half of ADR-043 + ADR-042.

New:
- DecisionExplanation, ExplainPolicy, ExplainRule DTOs in
  com.getaxonflow.sdk.types. Jackson @JsonIgnoreProperties(ignoreUnknown=
  true) for ADR-043 forward-compat with future platform fields.
- AxonFlow.explainDecision(decisionId) + explainDecisionAsync calling
  GET /api/v1/decisions/:id/explain. URL-encodes the decision ID.
  Rejects null/empty with IllegalArgumentException.
- AuditSearchRequest builder gains decisionId/policyName/overrideId;
  new JSON properties serialize only when set via @JsonInclude(NON_NULL).

Version: 5.3.0 -> 5.4.0 (pom.xml).

Tests (8 new, all passing via WireMock):
- explainDecision: null + empty rejection, full payload parse with URL
  assertion, forward-compat with unknown fields.
- searchAuditLogs: new filters serialize when set, absent when unset.
- DTO null-safety: DecisionExplanation policyMatches defaults to empty
  when constructor receives null; ExplainPolicy defaults.

Companion to platform v7.1.0 (axonflow-enterprise PR #1605), Go SDK
v5.4.0 (PR #122), Python v6.4.0 (PR #141), TS v5.4.0 (PR #175).

* fix: use path-segment encoding for explainDecision decision ID

URLEncoder.encode() is application/x-www-form-urlencoded — spaces become
'+' rather than '%20'. That's wrong for a path segment: the server parses
the URL path segment-by-segment and '+' is a literal character there.
Go / Python / TypeScript all path-encode; Java was the outlier.

Fix by replacing '+' with '%20' in the URLEncoder output. That converts
the form-encoded string to a valid percent-encoded path segment, with
every other character (including literal '+' in the input -> '%2B')
handled correctly. Two regression tests lock in the semantics.
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