Guided flow · ECZ-ID SDK Passport™
SDK guided flow
Carry a published SDK through the Accountability Chain: its publisher, its identity across languages and registries, the publisher context consumers see, carrying ECZ-ID context downstream, and verification in the consumer’s CI.
- Publisher identity
- SDK identity
- Publisher context
- Carry ECZ-ID context
- Downstream use
- Re-verify
Steps at a glance · what is live today
Live in production and publicly readable, with no account and no key.
GoalResolve the Business Passport of the publisher that answers for the SDK.
Why it mattersEvery child Passport resolves to one accountable organisation. A relying party who reaches the SDK can always find who stands behind it, without asking.
Prerequisites
- The SDK's ECZ-ID, or the parent ECZ-ID it names.
Example
curl -s https://api.ecocitizenz.com/api/p/ECZ-GB-RBS1NW.jsonExpected output
{
"ecz_id": "ECZ-GB-RBS1NW",
"resolver_v2": {
"record_type": "ECZ_ID_PARENT",
"state": {
"lifecycle_state": "ACTIVE",
"parent_tier": "VERIFIED",
"reliance_level": "PARENT_IDENTITY_ONLY"
},
"reliance": {
"can_rely_on": ["record_existence", "active_parent_state",
"current_parent_tier", "public_resolver_visibility"],
"reverify_before_reliance": true
}
}
}This is the operator record behind this site. Read parent_tier_context.tier_meaning on a child record: a parent tier is never inherited by a machine.
What this proves
- An accountable organisation exists and is publicly resolvable.
- Its current lifecycle state and parent tier, at the moment you read them.
What this does not prove
- That the organisation authorised any particular action by the SDK.
- That the machine itself is verified, safe or compliant.
Live in production and publicly readable, with no account and no key.
GoalGive the SDK a free ECZ-ID Passport and declare it where its ecosystem already looks.
Why it mattersOne SDK is one Passport across languages and registries. npm, PyPI and other channels are bindings; versions are history; a different library is a second Passport.
Prerequisites
- A library you publish.
- One identifier: its repository, its package or its SDK name.
Example
# package.json
# "ecz_id": "ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD",
# "resolver_backlink": "https://resolver.ecocitizenz.org/p/ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD"
# pyproject.toml
[tool.ecz_id]
ecz_id = "ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD"
resolver_backlink = "https://resolver.ecocitizenz.org/p/ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD"Check
npx -y @ecocitizenz/ecz-id-mcp-verifier check --target @ecocitizenz/ecz-id-mcp-verifier --target-type npm_packageExpected output
{
"target_type": "npm_package",
"policy_mode": "OPEN",
"result_state": "NO_PUBLIC_RESOLVER_PROOF_FOUND",
"reason_codes": ["NO_PUBLIC_RESOLVER_PROOF_FOUND", "RESOLVER_READ_ONLY",
"LOCAL_POLICY_DECIDES"],
"primary_action": "CHOOSE_OPERATOR_PATH",
"exit_code": 0
}The verifier package holds no SDK Passport yet; ecz-id on PyPI returned the same that day.
What this proves
- That the machine has a persistent, publicly resolvable identity under an accountable organisation, once issued and declared.
What this does not prove
- That the machine is safe, secure, correct or verified. A free Passport never claims that.
- Control of any native identity. A declaration is a pointer; only a proven binding proves.
Live in production and publicly readable, with no account and no key.
GoalPut the SDK’s ECZ-ID where consumers already look: the package manifest and the README.
Why it mattersA consumer deciding whether to depend on a library should reach its accountable publisher from the package itself.
Prerequisites
- The SDK’s Passport.
Example
# pyproject.toml
[tool.ecz_id]
ecz_id = "ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD"
resolver_backlink = "https://resolver.ecocitizenz.org/p/ECZ-GB-EXAMPL::SDK_PASSPORT-AB12CD"
# package.json carries the same two fields: "ecz_id" and "resolver_backlink"What this proves
- Where the publisher says the package belongs.
What this does not prove
- That the package is the publisher’s until a binding is proven.
- That the code is safe.
This happens in the integrator’s own system.
GoalWhen your SDK acts for its caller, let the caller’s own identity and Intent reference pass through unchanged.
Why it mattersAn SDK is usually not the actor; the application calling it is. Passing the caller’s context through keeps the chain intact instead of hiding the real actor behind the library.
Prerequisites
- Your SDK’s public API.
Example
export interface ActionOptions {
/** The calling machine's ECZ-ID. Passed through, never replaced. */
actorEczId?: string;
/** The caller's Intent reference, carried to your logs unchanged. */
intentRef?: { intent_id: string; version: number };
}What this proves
- Nothing on its own. It keeps the actor visible to the systems downstream.
What this does not prove
- That the caller is authorised. That is the caller’s Intent.
ReferenceCarry IntentECZ-ID format
Live in production and publicly readable, with no account and no key.
GoalLet consumers check the SDK’s public state in their own CI before they ship it.
Why it mattersA dependency is a reliance decision made once and executed forever. A CI gate makes it a decision re-made on every build.
Prerequisites
- A GitHub Actions workflow in the consuming project.
Example
# .github/workflows/ecz-id.yml — fails the job when proof is missing
- uses: Ecocitizenz/ecz-id-mcp-verifier@v0.9.0
with:
target: ${{ env.COUNTERPARTY_ECZ_ID }}
policy: REQUIREUnder REQUIRE the job fails when proof is missing; under OPEN it reports and passes. Both exit codes were measured.
What this proves
- The SDK’s published state at build time.
What this does not prove
- That the code is free of vulnerabilities.
ReferenceGitHub ActionResultStates
Live in production and publicly readable, with no account and no key.
GoalLet anyone who was not there re-check the SDK's public state, now and in CI.
Why it mattersEvery other link ends with a reader who was not present. Re-verifying closes the chain: the record is re-resolved live, never trusted from a cache.
Prerequisites
- Node 22.14+ for the verifier (its declared engine), or any HTTP client for the record.
Example
npx -y @ecocitizenz/ecz-id-mcp-verifier check --target @ecocitizenz/ecz-id-mcp-verifier --target-type npm_package --policy REQUIRE
# .github/workflows/ecz-id.yml — fails the job when proof is missing
- uses: Ecocitizenz/ecz-id-mcp-verifier@v0.9.0
with:
target: ${{ env.COUNTERPARTY_ECZ_ID }}
policy: REQUIREExpected output
{
"target_type": "npm_package",
"policy_mode": "OPEN",
"result_state": "NO_PUBLIC_RESOLVER_PROOF_FOUND",
"reason_codes": ["NO_PUBLIC_RESOLVER_PROOF_FOUND", "RESOLVER_READ_ONLY",
"LOCAL_POLICY_DECIDES"],
"primary_action": "CHOOSE_OPERATOR_PATH",
"exit_code": 0
}Under REQUIRE the same check exits 1 until the SDK’s proof is published.
What this proves
- The current published state, at the moment of the check, read live.
What this does not prove
- Safety, security, certification, compliance or approval.
- Anything about the state a minute later. Re-check before each reliance.
Where next
This page is explanation, not authority. Current state is only ever the live Resolver record. Commands were run read-only on 2026-10-10; illustrative examples are labelled.
