Documentation
¶
Overview ¶
Package clearing is the official Go SDK for the Clearing economic-principal (EPID) service. It composes self-contained primitives (resilient resolution, RSA request signing, and the canonical-kind taxonomy — all vendored under internal/) into three capability tiers with a uniform shape across the Go / Python / TypeScript SDKs:
L1 ResolveClient — read: Resolve / GetByEPID / Kinds (cache + breaker) L2 SourceClient — register: Ensure / Link / Affiliate (auto request signing) L3 UnifyClient — unify: ProveKey / SubmitVerifiedAttr / Bind / LinkRealm
The tier is the permission boundary: constructing L2 or L3 requires a source identity and a private key, so an ordinary read-only consumer cannot obtain the write/unify handles from the type system alone.
The SDK hides the signing details the wire protocol exposes: the three signing headers (X-Clearing-Source / X-Clearing-Signature / X-Clearing-Timestamp), base64(std) encoding, Ed25519 vs RSA usage, the challenge fetch->sign->submit flow, and the rule that an attribute assertion's verifier_sig is signed over the request body excluding the verifier_sig field itself.
Index ¶
- Constants
- Variables
- type APIError
- type AttrAssertion
- type ClearingClient
- type DedupResult
- type Ensured
- type Identity
- type Options
- type ResolveClient
- type Resolved
- type SourceClient
- func (c *SourceClient) Affiliate(ctx context.Context, subjectEPID, relation, targetEPID string) error
- func (c *SourceClient) Ensure(ctx context.Context, id Identity) (Ensured, error)
- func (c *SourceClient) Link(ctx context.Context, id Identity, targetEPID string) error
- func (c *SourceClient) RotateKey(s requestSigner)
- type UnifyClient
- func (c *UnifyClient) Bind(ctx context.Context, subjectEPID, targetEPID string, sk, tk ed25519.PrivateKey) (DedupResult, error)
- func (c *UnifyClient) LinkRealm(ctx context.Context, orgEPID string, realm Identity, ...) error
- func (c *UnifyClient) ProveKey(ctx context.Context, epid string, edPriv ed25519.PrivateKey) (DedupResult, error)
- func (c *UnifyClient) SubmitVerifiedAttr(ctx context.Context, a AttrAssertion) (DedupResult, error)
Constants ¶
const ( RelationMemberOf = "member_of" RelationAccountableFor = "accountable_for" )
Relation enumerates economically-neutral affiliation edges.
const ContractVersion = "1.0.0"
ContractVersion is the OpenAPI contract major.minor.patch this SDK targets. Integration tests compare it against the live server info.version for compat.
Variables ¶
var ( // ErrNotRegistered: the principal/identity is authoritatively absent (404). // Re-exported from epidclient so L1 and L2/L3 share one sentinel. ErrNotRegistered = epidclient.ErrNotRegistered // masked; the caller decides fail-open vs fail-closed. ErrUnavailable = epidclient.ErrUnavailable // ErrPermission: source not authorized for this identity, or admin/governance // gate rejected (401/403). ErrPermission = errors.New("clearing: permission denied") // ErrConflict: unification/registration conflict (409) — identity already // mapped, challenge expired/used, binding not proven, low-tier auto-merge. ErrConflict = errors.New("clearing: conflict") // ErrInvalid: semantically invalid request (400/422) — bad body, unknown // kind/relation, self-merge, malformed key. ErrInvalid = errors.New("clearing: invalid request") // ErrRateLimited: too many challenges / requests (429). ErrRateLimited = errors.New("clearing: rate limited") )
Stable SDK error sentinels. Consumers branch on these (errors.Is) to choose fail-open/closed; the SDK never silently fabricates a fallback.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
Status int // HTTP status code
Code string // server "error" envelope code (e.g. not_registered)
Detail string // optional human detail (500 only)
// contains filtered or unexported fields
}
APIError carries the server's stable machine code + HTTP status alongside the classified sentinel, so consumers can log precisely while branching coarsely.
type AttrAssertion ¶
type AttrAssertion struct {
EPID string
AttrType string // phone | email | gov_id ...
SaltedHash string
AssuranceTier int
Method string
}
AttrAssertion is a verifier's deduplication assertion for a strong attribute. The plaintext never leaves the verifier; only a salted hash is transmitted. Sig is filled by the SDK (RS256 over the canonical body, base64-std) — callers never set it.
type ClearingClient ¶
type ClearingClient struct {
L1 *ResolveClient // always present
L2 *SourceClient // nil unless constructed with a source key
L3 *UnifyClient // nil unless constructed with a source key
}
ClearingClient is the unified facade. Which tiers are non-nil depends on the constructor used, so capability is bound to the construction credential:
NewReadOnly -> L1 only NewSource -> L1 + L2 NewUnify -> L1 + L2 + L3
func NewReadOnly ¶
func NewReadOnly(baseURL string, opt Options) *ClearingClient
NewReadOnly builds an L1-only client. Ordinary read-only consumers use this; the type system denies them L2/L3 (both stay nil).
func NewSource ¶
func NewSource(baseURL, sourceID string, priv *rsa.PrivateKey, opt Options) *ClearingClient
NewSource builds an L1+L2 client for an authenticated event source. It requires the source identity + RSA private key.
func NewUnify ¶
func NewUnify(baseURL, sourceID string, priv *rsa.PrivateKey, opt Options) *ClearingClient
NewUnify builds a full L1+L2+L3 client for a unification orchestrator. It requires the source identity + RSA private key (used for the verified-attr verifier_sig and realm-link request signing).
func (*ClearingClient) Version ¶
func (c *ClearingClient) Version() string
Version returns the OpenAPI contract version this SDK targets.
type DedupResult ¶
DedupResult is the outcome of a unification (key-proof / verified-attr / binding). NeedsReview is only meaningful for verified-attr (low-tier hits).
type Ensured ¶
type Ensured struct {
EPID string
CanonicalKind string
Created bool // true=newly created, false=idempotent hit
}
Ensured is the ensure (idempotent adopt) result.
type Identity ¶
type Identity struct {
AuthInstanceID string // issuing auth instance (used as the source id on signed writes)
Kind string // external kind (user/agent/client/realm/provider...)
Key string // stable principal key within that auth instance
}
Identity is the external identity natural key (the realm is not part of the key).
type Options ¶
type Options struct {
// L1 resilience (forwarded verbatim to epidclient.Options).
TTL time.Duration
NegativeTTL time.Duration
FailureThreshold int
OpenTimeout time.Duration
// HTTPClient is used by L2/L3 (and L1's HTTP backend). Defaults to a client
// with WriteTimeout. Injected so tests can stub the transport.
HTTPClient *http.Client
// WriteTimeout bounds L2/L3 calls when HTTPClient is not supplied (default 5s).
WriteTimeout time.Duration
// Now is an injectable clock (timestamps + resilience). Defaults to time.Now.
Now func() time.Time
}
Options tunes both L1 resilience (forwarded to epidclient) and the HTTP transport shared by L2/L3. Zero values get industrial defaults.
type ResolveClient ¶
type ResolveClient struct {
// contains filtered or unexported fields
}
ResolveClient is the L1 read tier. It is a thin facade over epidclient.Client (cache + single-flight + circuit breaker), so it inherits the resilience and degradation semantics implemented there.
func (*ResolveClient) GetByEPID ¶
GetByEPID fetches the active principal for an EPID (follows merges). It bypasses the identity cache (different key space) and calls GET /v1/principals/:epid.
func (*ResolveClient) Invalidate ¶
func (c *ResolveClient) Invalidate(id Identity)
Invalidate drops the cached resolution for an identity (after a known merge/link, callers clear the hot entry).
func (*ResolveClient) Kinds ¶
Kinds returns the authoritative external→canonical kind mapping (cached). On unreachable server it falls back to the compiled-in canonicalkind table and records that the result is degraded (see kinds.go).
type Resolved ¶
type Resolved struct {
EPID string
CanonicalKind string
Status string // ACTIVE | MERGED | SUSPENDED (resolve always follows to active)
}
Resolved is the active-principal projection returned by resolve/getByEPID.
type SourceClient ¶
type SourceClient struct {
// contains filtered or unexported fields
}
SourceClient is the L2 registration tier. Only an authenticated event source constructs it, because it requires the source identity + RSA private key. Every write is source-signed automatically.
func (*SourceClient) Affiliate ¶
func (c *SourceClient) Affiliate(ctx context.Context, subjectEPID, relation, targetEPID string) error
Affiliate writes an economically-neutral relation (member_of / accountable_for) between two principals (source-signed).
func (*SourceClient) Ensure ¶
Ensure idempotently adopts an external identity as an economic principal and returns its EPID. body.auth_instance_id must equal the signing source (server enforces, else ErrPermission). Safe to retry (idempotent + re-sign).
func (*SourceClient) Link ¶
Link attaches an unregistered identity to an existing EPID (source-signed).
func (*SourceClient) RotateKey ¶
func (c *SourceClient) RotateKey(s requestSigner)
RotateKey swaps the signing private key (key rotation; ensure is idempotent so re-signing after rotation is safe).
type UnifyClient ¶
type UnifyClient struct {
// contains filtered or unexported fields
}
UnifyClient is the L3 unification tier. It orchestrates the challenge fetch->sign->submit flow and hides the Ed25519/RSA + base64(std) details. It holds the source RSA key (for the verified-attr verifier_sig and realm-link request signing) — so, like L2, only an authenticated source/orchestrator can construct it.
func (*UnifyClient) Bind ¶
func (c *UnifyClient) Bind(ctx context.Context, subjectEPID, targetEPID string, sk, tk ed25519.PrivateKey) (DedupResult, error)
Bind performs a dual-binding merge: it starts a binding challenge, has both sides sign it with their Ed25519 keys, and submits the proofs. Both keys must already be registered active anchors for their EPIDs (via ProveKey first).
func (*UnifyClient) LinkRealm ¶
func (c *UnifyClient) LinkRealm(ctx context.Context, orgEPID string, realm Identity, adminKey ed25519.PrivateKey) error
LinkRealm projects an org realm identity into the org EPID. The whole request is source-signed by the realm's source (realm.AuthInstanceID must equal the signing source), and admin control is proven by signing the canonical org-admin message with the org's registered Ed25519 admin key.
func (*UnifyClient) ProveKey ¶
func (c *UnifyClient) ProveKey(ctx context.Context, epid string, edPriv ed25519.PrivateKey) (DedupResult, error)
ProveKey deduplicates by key control: it fetches a key-proof challenge, signs it with edPriv, and submits public key + fingerprint + signature. Same key across sources => same principal. No source assertion is involved.
func (*UnifyClient) SubmitVerifiedAttr ¶
func (c *UnifyClient) SubmitVerifiedAttr(ctx context.Context, a AttrAssertion) (DedupResult, error)
SubmitVerifiedAttr submits a verifier's deduplication assertion. The SDK signs the canonical assertion body (WITHOUT verifier_sig — that field is json:"-" on the server) with the source RSA key and attaches it base64(std) as verifier_sig (closing the base64 footgun the protocol exposes).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
canonicalkind
Package canonicalkind is the single authoritative taxonomy of economic principal kinds (defined by Clearing, one source of truth).
|
Package canonicalkind is the single authoritative taxonomy of economic principal kinds (defined by Clearing, one source of truth). |
|
contract
Package contract is the Go reference implementation for the cross-language golden vectors.
|
Package contract is the Go reference implementation for the cross-language golden vectors. |
|
epidclient
Package epidclient is the resilient EPID resolution client.
|
Package epidclient is the resilient EPID resolution client. |
|
sourcesign
Package sourcesign implements source-signed write authentication: deterministic canonical JSON plus RS256 (RSA-PKCS1v15 + SHA-256) sign/verify.
|
Package sourcesign implements source-signed write authentication: deterministic canonical JSON plus RS256 (RSA-PKCS1v15 + SHA-256) sign/verify. |