ISSUE · CREDENTIAL TYPES · SPECIFICATION
Whatever you already know, in a format a stranger can read.
A credential type is three decisions: what the statement is called, which claims it carries, and which of those claims the holder may open one at a time. Everything else — the signature, the binding, the withdrawal — is the same for every type.
Specification register. The plain-language version is the issue overview.
One thing to hold on to: the type does not decide what the verifier learns. The holder does, at the moment of showing, from inside whatever the type carries.
What this issuer publishes today
A wallet does not guess. Before it asks a person for anything it fetches the issuer's metadata and reads what is on offer. Here is that document, fetched on 2026-08-27, unedited.
GET https://id.orbis.id/.well-known/openid-credential-issuer — 200
{
"credential_issuer": "https://id.orbis.id",
"credential_endpoint": "https://id.orbis.id/credential",
"authorization_servers": ["https://id.orbis.id"],
"batch_credential_issuance": { "batch_size": 10 },
"credential_configurations_supported": {
"iVita.Membership": {
"format": "dc+sd-jwt",
"vct": "iVita.Membership",
"proof_types_supported": {
"jwt": { "proof_signing_alg_values_supported": ["ES256"] }
}
}
}
} Fetch it yourself:
curl -s https://id.orbis.id/.well-known/openid-credential-issuer | jq .
Read that carefully and it tells you the size of the catalogue: one configuration,
named iVita.Membership, in one format. Anybody claiming a longer list
should be asked for the same document.
The format, and why only one
The format is dc+sd-jwt — an SD-JWT VC. It is a signed token in which each
subject claim has been replaced by a salted digest, so the holder can reveal claims one
at a time and the signature still checks out over what is left.
We issue that and nothing else. Not mdoc, not JSON-LD with a data-integrity proof, not AnonCreds. Multi-format issuance is not built. A page that listed four formats and shipped one would be the exact thing this site exists not to be.
-
Credential format
SD-JWT VC, published as
dc+sd-jwt -
Issuance protocol
OpenID for Verifiable Credential Issuance
-
Presentation protocol
OpenID for Verifiable Presentations
-
Signature algorithm
ES256, on the P-256 curve — issuer and holder both
-
Issuer identifier
did:web, resolved from your own domain -
Status mechanism
IETF Token Status List, signed, read whole
Those rows carry no state marks, and the omission is deliberate: the states on this site resolve from the register and are never typed. One row per standard, each with its own state, belongs on the standards page.
What a schema actually looks like
A worked example, not a capture. Registered claims sit in the clear because a verifier needs them to do its job; every subject claim has been replaced by a digest, and the values travel separately as disclosures the holder chooses to attach.
Worked example · the payload of an SD-JWT VC
{
"vct": "iVita.Membership",
"iss": "did:web:orbis.id",
"iat": 1787844699,
"cnf": { "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." } },
"_sd_alg": "sha-256",
"_sd": [
"iVs2fH9...", // in_good_standing
"qL7dK2p...", // member_number
"8Ykm4Rt...", // member_since
"Zx1nQ0b..." // tier
]
} And one disclosure, which is what the holder attaches when they decide to open a claim:
WyJfMjZiYzRMVC1hYzZxMktJNmNCVyIsICJpbl9nb29kX3N0YW5kaW5nIiwgdHJ1ZV0
~ decodes to ~
["_26bc4LT-ac6q2KI6cBW", "in_good_standing", true]
salt claim name claim value cnf is the whole holder-binding story in one field: it names the public key
of the device the credential was issued to. A copy of the token on another phone cannot
answer a challenge with the matching private key, so it is not a usable copy.
Choosing the claims is choosing what can stay behind
Design the type around the questions people will actually be asked, and each of those answers becomes something the holder can open on its own. Put a member number in the same claim as the standing flag and you have made them inseparable forever.
Illustration · a credential, drawn
- in_good_standing shared
- member_number never sent
- member_since never sent
- tier never sent
What the counterparty received:
Adding a second type
Technically it is a new entry in the document at the top of this page and a schema the wallet can render. Practically it is a conversation with us, because sign-up and type administration are not self-service. That is the honest cost of a second row today, and it is a cost we would rather name than hide behind a form.
Check the catalogue yourself
One command lists every credential configuration this issuer will admit to. If it returns more rows than this page shows, this page is stale and you should trust the command.
curl -s https://id.orbis.id/.well-known/openid-credential-issuer \
| jq '.credential_configurations_supported | keys' Answered on 2026-08-27 with a list of one.
What is real here.
Issuance and selective disclosure run on the live cell and you have the command that proves the catalogue. What is not real is a catalogue: there is one type, one format, and no self-service way to add a second.
- PLANNED A wallet a person installs from an app store. wallet-native You cannot hold a credential on a phone you own. Everything a person would do with a proof waits behind this.
The register holds 17 live · 2 partial · 2 planned · 5 not yet.
3 of the 4 capabilities this page depends on have no row in the register yet, so this page will not print a state for them. They are named rather than dropped, because a slice that silently shortens itself is the same defect as a claim with no receipt.
- vc-issuance
- selective-disclosure
- credential-types
The register route serves, but it carries no row for these yet. List what it does carry:
curl -s https://id.orbis.id/api/site/register | jq -r '.entries[].slug' Straight answers
- Can I issue an mDL or an ISO mdoc?
- No. We issue SD-JWT VC only. Multi-format issuance is not built and we are not going to imply it is by listing formats in a table with no state beside them.
- Can I define my own claim names?
- Yes — the type is yours and the claims in it are yours. What you cannot do today is define one without us, because type administration is not self-service.
- Does the verifier need my schema to check a proof?
- Not to check that it is genuine. The four checks work from the token, your key document and the status list. It needs your schema to display it well and to decide whether the claims mean what it needs them to mean.
- What holds the values that are not disclosed?
- The holder's wallet. They travel with the credential and never leave the device unless the holder opens them. What the verifier gets is the token plus exactly the disclosures attached to it — nothing greyed out, nothing withheld-but-present.
- Where is the generated API contract?
- Here, generated from the running service.
Do not trust us. Check us.