License consistency + explicit SaaS/hosted multi-tenant IdP terms
Filing target: github.com/wangkanai/federation — LICENSE/metadata Bug, Priority P0 (per research
009 §8
P0 row, finding F7).
Motivated by: research
agile/research/009-refactoring-shared-federation-domain-from-account/report.md
§8 P0 row + Finding F7. Drafted from epic
031-oss-contribution-parallel-track/031-01-p0-license-metadata-issue.
Problem statement
The wangkanai/federation repository currently ships inconsistent license
metadata across the raw LICENSE file, the README.md, and the published
NuGet nuspec. Downstream consumers (NuGet clients, license scanners, hosted
service operators, compliance tooling, and contributors) treat each of those
artifacts as authoritative, and the three do not agree.
Finding F7 (verbatim, research 009 §3 row 7, consensus HIGH, Investigator E3)
License mismatch on federation: live main LICENSE = SSPL v1 (Feb 2026 commit);
README and old published 3.0.0 nuspec claim Apache-2.0. Foundation + other
listed Wangkanai.* = Apache-2.0.
Three-artifact mismatch table
Why this is a consumption blocker, not a documentation nit
- Legal clarity gap. A consumer — internal team or external — who reads
the README sees Apache-2.0 and assumes permissive use. The raw LICENSE
file says SSPL v1, which conditions the grant on not offering the work
"as a service" to third parties without publishing the complete
corresponding source. The two statements are not reconcilable as a
consumer-disclosure matter.
- SSPL v1 "service" trigger is exactly the SaaS / hosted / multi-tenant
IdP deployment model. SSPL v1 §13 fires when the work is offered as a
hosted/managed network-accessible service to third parties. The
Federation package's primary purpose is to be an OIDC identity-provider
library — i.e. something designed to be run as a hosted IdP. The
README/nuspec's permissive claim obscures this.
- NuGet package drift. The published
3.0.0 package on nuget.org
still carries Apache-2.0 metadata from a prior monorepo state (net8 /
pre-SSPL / pre-current-tree) per F6/F7. A consumer pinning a major
version gets one license story; a contributor reading main gets
another; both are wrong relative to each other and to the raw file.
For consumers building multi-tenant OIDC / identity-provider platforms
on top of wangkanai/federation, the license mismatch is the gating
question that blocks any hard dependency until the upstream metadata is
made internally consistent and the SaaS / hosted / multi-tenant IdP
deployment model is addressed explicitly.
RiverSync usage context
RiverSync is a six-app product platform. Its OIDC identity-provider role
is centralized in a single application (Account); the other five
(Portal, Admin, Partners, Pipeline, Field) participate strictly
as OIDC relying parties. The following four anchors explain why the
SaaS / hosted / multi-tenant IdP wording matters to us — and why we are
asking this question rather than quietly forking.
-
Thin Common foundation (epic 029).
Epic 029 — Common OSS Foundation Layer
establishes RiverSync.Common.Domain as a thin shell depending on
Wangkanai.Domain and Wangkanai.System, with client-side federation
pieces (claims codec, OIDC RP wiring) already extracted into
Common/src/Claims/ and Common/src/Web/ without issuer-side leakage.
This is the Option A recommendation from research 009 §7: thin
extraction in Common, not a full internal fork.
-
Planned thin extraction of federation models (epic 030).
Epic 030 — Extract Federation Domain Models To Common
is the follow-on that would push consumable model shapes (Tenant,
Permission, RolePermission with allowed-scopes + one-way narrowing) into
Common.Domain, leaving Account as the persisted IdP matrix and
issuer. Neither 029 nor 030 pins Wangkanai.Federation today — both
are blocked on the license question being resolved first (F7).
-
Cross-tenant ViewAsContext precedent (epic 018).
Epic 018 — Cross-Tenant Access (View-As)
established the ViewAsContext pattern — anchored at
Common/src/Web/ViewAsContext.cs —
for safely traversing tenant boundaries in the platform IdP without
leaking issuer responsibilities. This is exactly the shape of a
multi-tenant IdP pattern whose hosted/SaaS deployment semantics need
to be legible from upstream license metadata.
-
ARCH:VI — Account is the sole writer.
Per architecture rule
.claude/rules/architecture/federation-auth.md
(extract ARCH:VI):
Account is the sole platform OIDC/OAuth2 identity provider — the
only issuer of the federated token every app trusts.
- The other five product apps (Portal, Admin, Partners, Pipeline, Field)
participate strictly as OIDC relying parties; none runs its own
authorization server or credential store.
Common provides consumable shapes (claims codec, RP wiring,
ViewAsContext); it does NOT host a token issuer.
No timeline promises (explicit)
To be unambiguous about what this issue is not asking:
- No timeline promise. This issue does not commit RiverSync to any
particular release date for adopting any upstream release. Internal
sequencing is governed separately by our own epic planning and may
change without notice to this issue.
- No adoption commitment. RiverSync has not committed to taking a
hard Wangkanai.Federation dependency even after this issue is
resolved. The thin Common strategy in 029/030 is OSS-agnostic and is
being executed on Wangkanai.Domain + Wangkanai.System today; any
deeper Federation adoption is contingent on legal/architectural review
on our side.
- No licensing-philosophy request. We are not asking upstream to
change their licensing philosophy — only to reconcile the raw LICENSE
vs README/nuspec and to state the hosted/SaaS/multi-tenant IdP
boundaries explicitly. The license of record (Apache-2.0 vs SSPL v1
vs something else) is a project governance decision and not ours to
make.
Request
We respectfully ask the wangkanai/federation maintainers to address
this gap with the following three coordinated changes:
-
Reconcile the LICENSE-vs-README/nuspec mismatch. Pick the intended
license of record for the current main branch and update all three
artifacts so they agree. Either:
- Apache-2.0 in LICENSE + README + nuspec (the permissive reading
the README/nuspec currently imply), or
- SSPL v1 in LICENSE + README + nuspec (the substantive reading
the raw file currently asserts).
Do not leave the three artifacts in disagreement. If a different
license is preferred, document the change in a clearly-linked
CHANGELOG / release-notes entry so consumers can re-pin
deliberately.
-
Add explicit SaaS / hosted / multi-tenant IdP terms. Regardless of
which license is chosen, add language (either inline in LICENSE, in
a LICENSE-COMPATIBILITY.md companion, or in a clearly-linked
README.md section) that explicitly addresses:
- Re-hosting rights — under which terms (if any) may the
Federation package be embedded in a hosted / managed multi-tenant
IdP service that is offered to third-party customers? (Apache-2.0
makes this unambiguous; SSPL makes this ambiguous and needs the
scope of "the work" stated explicitly.)
- Network-copyleft boundaries — if upstream chooses to keep SSPL
on main, what is the exact scope of "the work" a hosted deployer
must publish under SSPL? Specifically: just the unmodified
Federation package; the hosted service as a whole; or modifications
and derivative works of Federation only?
- Hosted multi-tenant boundaries — what counts as "offering the
work as a service" when the SaaS in question is itself an OIDC IdP
whose product is identity / claims issuance (not a "feature" of an
unrelated product)? Federation is an IdP library; SaaS use IS the
primary use case, not an edge case.
-
Document the choice in a LICENSE-COMPATIBILITY.md (or equivalent)
so downstream consumers — multi-tenant OIDC platforms in particular —
can self-assess without re-deriving it. Our compliance posture for
ARCH:VI requires that we can name, in writing, the license under
which each package we depend on is offered. "Probably permissive
because the README says so while the raw file says copyleft" is not
a posture; it is a risk. Either the SPDX headers need to agree, or an
explicit policy decision from the maintainer needs to be recorded in
the repo (a LICENSE-COMPATIBILITY.md, a maintainer-signed addendum
to README, or equivalent). RiverSync is happy to review any proposed
wording and to share a brief non-binding read of how the resolution
would land on our side — none of that is contingent on the
resolution itself.
Why now
This is a pre-existing gap, not a new regression — but the timing is
right for three converging reasons that make the platform's
multi-tenant IdP usage visible upstream:
- The thin Common strategy is already in flight (epics 029 and
030), so the consuming platform's pattern of "shared federation
vocabulary lives in OSS where it can, in platform where it must" is
no longer hypothetical — it is the direction we are executing.
- The cross-tenant /
ViewAsContext precedent (epic 018) makes our
multi-tenant IdP usage of federation-shaped primitives a real,
shipped pattern on our side, not a roadmap sketch. That makes the
license question a current-day gating decision rather than a
future-tense one.
- A clean resolution unblocks other consumption. Per research 009
§8, the license clarity (P0) is prerequisite for any subsequent
OSS work — the scoped Permission / RolePermission models (P1), the
multi-tenant Tenant + composite identity helpers (P1), the
permission scope codec (P1), and the SaaS / hosted entitlement shapes
(P2) all depend on the federation package being legally consumable.
P0 first; the rest of the backlog follows.
Without explicit hosted/SaaS terms, multi-tenant OIDC platforms have to
make a worst-case assumption about the SSPL §13 network-copyleft
trigger — and that worst-case is the one that blocks any production
pin. This issue is asking for the language to be made unambiguous, not
for the underlying license to change.
References
Drafted by RiverSync for upstream filing against wangkanai/federation;
not yet filed. Once filed, the upstream URL will replace this header note
and the tracker row in docs/oss-contributions.md
will be updated to Filed.
License consistency + explicit SaaS/hosted multi-tenant IdP terms
Problem statement
The
wangkanai/federationrepository currently ships inconsistent licensemetadata across the raw
LICENSEfile, theREADME.md, and the publishedNuGet nuspec. Downstream consumers (NuGet clients, license scanners, hosted
service operators, compliance tooling, and contributors) treat each of those
artifacts as authoritative, and the three do not agree.
Finding F7 (verbatim, research 009 §3 row 7, consensus HIGH, Investigator E3)
Three-artifact mismatch table
wangkanai/federationLICENSE(live main, Feb 2026 commit)wangkanai/federationREADME.mdnuget.org/packages/Wangkanai.Federation/3.0.0.nuspecwangkanai/foundationLICENSE+README.md(contrast)Why this is a consumption blocker, not a documentation nit
the README sees Apache-2.0 and assumes permissive use. The raw
LICENSEfile says SSPL v1, which conditions the grant on not offering the work
"as a service" to third parties without publishing the complete
corresponding source. The two statements are not reconcilable as a
consumer-disclosure matter.
IdP deployment model. SSPL v1 §13 fires when the work is offered as a
hosted/managed network-accessible service to third parties. The
Federation package's primary purpose is to be an OIDC identity-provider
library — i.e. something designed to be run as a hosted IdP. The
README/nuspec's permissive claim obscures this.
3.0.0package on nuget.orgstill carries Apache-2.0 metadata from a prior monorepo state (net8 /
pre-SSPL / pre-current-tree) per F6/F7. A consumer pinning a major
version gets one license story; a contributor reading main gets
another; both are wrong relative to each other and to the raw file.
For consumers building multi-tenant OIDC / identity-provider platforms
on top of
wangkanai/federation, the license mismatch is the gatingquestion that blocks any hard dependency until the upstream metadata is
made internally consistent and the SaaS / hosted / multi-tenant IdP
deployment model is addressed explicitly.
RiverSync usage context
RiverSync is a six-app product platform. Its OIDC identity-provider role
is centralized in a single application (
Account); the other five(
Portal,Admin,Partners,Pipeline,Field) participate strictlyas OIDC relying parties. The following four anchors explain why the
SaaS / hosted / multi-tenant IdP wording matters to us — and why we are
asking this question rather than quietly forking.
Thin Common foundation (epic 029).
Epic 029 — Common OSS Foundation Layer
establishes
RiverSync.Common.Domainas a thin shell depending onWangkanai.DomainandWangkanai.System, with client-side federationpieces (claims codec, OIDC RP wiring) already extracted into
Common/src/Claims/andCommon/src/Web/without issuer-side leakage.This is the Option A recommendation from research 009 §7: thin
extraction in Common, not a full internal fork.
Planned thin extraction of federation models (epic 030).
Epic 030 — Extract Federation Domain Models To Common
is the follow-on that would push consumable model shapes (Tenant,
Permission, RolePermission with allowed-scopes + one-way narrowing) into
Common.Domain, leavingAccountas the persisted IdP matrix andissuer. Neither 029 nor 030 pins
Wangkanai.Federationtoday — bothare blocked on the license question being resolved first (F7).
Cross-tenant ViewAsContext precedent (epic 018).
Epic 018 — Cross-Tenant Access (View-As)
established the
ViewAsContextpattern — anchored atCommon/src/Web/ViewAsContext.cs—for safely traversing tenant boundaries in the platform IdP without
leaking issuer responsibilities. This is exactly the shape of a
multi-tenant IdP pattern whose hosted/SaaS deployment semantics need
to be legible from upstream license metadata.
ARCH:VI — Account is the sole writer.
Per architecture rule
.claude/rules/architecture/federation-auth.md(extract ARCH:VI):
Accountis the sole platform OIDC/OAuth2 identity provider — theonly issuer of the federated token every app trusts.
participate strictly as OIDC relying parties; none runs its own
authorization server or credential store.
Commonprovides consumable shapes (claims codec, RP wiring,ViewAsContext); it does NOT host a token issuer.No timeline promises (explicit)
To be unambiguous about what this issue is not asking:
particular release date for adopting any upstream release. Internal
sequencing is governed separately by our own epic planning and may
change without notice to this issue.
hard
Wangkanai.Federationdependency even after this issue isresolved. The thin Common strategy in 029/030 is OSS-agnostic and is
being executed on
Wangkanai.Domain+Wangkanai.Systemtoday; anydeeper Federation adoption is contingent on legal/architectural review
on our side.
change their licensing philosophy — only to reconcile the raw LICENSE
vs README/nuspec and to state the hosted/SaaS/multi-tenant IdP
boundaries explicitly. The license of record (Apache-2.0 vs SSPL v1
vs something else) is a project governance decision and not ours to
make.
Request
We respectfully ask the
wangkanai/federationmaintainers to addressthis gap with the following three coordinated changes:
Reconcile the LICENSE-vs-README/nuspec mismatch. Pick the intended
license of record for the current main branch and update all three
artifacts so they agree. Either:
the README/nuspec currently imply), or
the raw file currently asserts).
Do not leave the three artifacts in disagreement. If a different
license is preferred, document the change in a clearly-linked
CHANGELOG/ release-notes entry so consumers can re-pindeliberately.
Add explicit SaaS / hosted / multi-tenant IdP terms. Regardless of
which license is chosen, add language (either inline in
LICENSE, ina
LICENSE-COMPATIBILITY.mdcompanion, or in a clearly-linkedREADME.mdsection) that explicitly addresses:Federation package be embedded in a hosted / managed multi-tenant
IdP service that is offered to third-party customers? (Apache-2.0
makes this unambiguous; SSPL makes this ambiguous and needs the
scope of "the work" stated explicitly.)
on main, what is the exact scope of "the work" a hosted deployer
must publish under SSPL? Specifically: just the unmodified
Federation package; the hosted service as a whole; or modifications
and derivative works of Federation only?
work as a service" when the SaaS in question is itself an OIDC IdP
whose product is identity / claims issuance (not a "feature" of an
unrelated product)? Federation is an IdP library; SaaS use IS the
primary use case, not an edge case.
Document the choice in a LICENSE-COMPATIBILITY.md (or equivalent)
so downstream consumers — multi-tenant OIDC platforms in particular —
can self-assess without re-deriving it. Our compliance posture for
ARCH:VI requires that we can name, in writing, the license under
which each package we depend on is offered. "Probably permissive
because the README says so while the raw file says copyleft" is not
a posture; it is a risk. Either the SPDX headers need to agree, or an
explicit policy decision from the maintainer needs to be recorded in
the repo (a
LICENSE-COMPATIBILITY.md, a maintainer-signed addendumto README, or equivalent). RiverSync is happy to review any proposed
wording and to share a brief non-binding read of how the resolution
would land on our side — none of that is contingent on the
resolution itself.
Why now
This is a pre-existing gap, not a new regression — but the timing is
right for three converging reasons that make the platform's
multi-tenant IdP usage visible upstream:
030), so the consuming platform's pattern of "shared federation
vocabulary lives in OSS where it can, in platform where it must" is
no longer hypothetical — it is the direction we are executing.
ViewAsContextprecedent (epic 018) makes ourmulti-tenant IdP usage of federation-shaped primitives a real,
shipped pattern on our side, not a roadmap sketch. That makes the
license question a current-day gating decision rather than a
future-tense one.
§8, the license clarity (P0) is prerequisite for any subsequent
OSS work — the scoped Permission / RolePermission models (P1), the
multi-tenant
Tenant+ composite identity helpers (P1), thepermission scope codec (P1), and the SaaS / hosted entitlement shapes
(P2) all depend on the federation package being legally consumable.
P0 first; the rest of the backlog follows.
Without explicit hosted/SaaS terms, multi-tenant OIDC platforms have to
make a worst-case assumption about the SSPL §13 network-copyleft
trigger — and that worst-case is the one that blocks any production
pin. This issue is asking for the language to be made unambiguous, not
for the underlying license to change.
References
agile/research/009-refactoring-shared-federation-domain-from-account/report.mdARCH:VI(Account as sole identity issuer; RP-onlyfederation) —
.claude/rules/architecture/federation-auth.mdagile/epics/029-common-oss-foundation-layer/epic.mdagile/epics/030-extract-federation-domain-models-to-common/epic.mdagile/epics/018-cross-tenant-access-view-as/epic.mdgithub.com/wangkanai/federation
and
nuget.org/packages/Wangkanai.Federation
docs/oss/drafts/.notes/031-01-T03-evidence.mdDrafted by RiverSync for upstream filing against
wangkanai/federation;not yet filed. Once filed, the upstream URL will replace this header note
and the tracker row in
docs/oss-contributions.mdwill be updated to
Filed.