Party Data Models
The IDK provides data models for representing parties, identities, tenants, and correlation identifiers. These models form the foundation for managing entities in credential ecosystems.
Overview
The party module follows an "everything is a party" pattern where:
- Parties are the central entity representing any actor (person, organization, service)
- Identities represent how a party presents itself in the credential ecosystem (issuer, verifier, holder)
- Tenants provide organizational isolation
- Correlation Identifiers link external identifiers (DIDs, X.509, email) to identities
Core Data Models
Party
A party represents any entity in the system:
- Android/Kotlin
- iOS/Swift
import com.sphereon.data.store.party.model.*
data class Party(
val partyId: String,
val tenantId: String,
val partyType: PartyType,
val origin: PartyOrigin,
val displayName: String,
val uri: String?,
val ownerId: String?,
val createdAt: Instant,
val updatedAt: Instant,
val deletedAt: Instant?
)
import SphereonDataStore
struct Party {
let partyId: String
let tenantId: String
let partyType: PartyType
let origin: PartyOrigin
let displayName: String
let uri: String?
let ownerId: String?
let createdAt: Date
let updatedAt: Date
let deletedAt: Date?
}
Party Types
Party types are extensible value classes:
- Android/Kotlin
- iOS/Swift
// Built-in party types
val naturalPerson = PartyType.NATURAL_PERSON // A human individual
val organization = PartyType.ORGANIZATION // Company, institution, legal entity
// Custom party types
val customType = PartyType("SERVICE")
val deviceType = PartyType("DEVICE")
// Built-in party types
let naturalPerson = PartyType.naturalPerson // A human individual
let organization = PartyType.organization // Company, institution, legal entity
// Custom party types
let customType = PartyType(value: "SERVICE")
let deviceType = PartyType(value: "DEVICE")
Party Origin
Indicates how the party was created:
| Origin | Description |
|---|---|
EXTERNAL | Synced from outside source (IdP, external system, import, auto-discovery) |
MANAGED | Created and managed natively within the system |
Identity
An identity represents a role that a party plays in the credential ecosystem:
- Android/Kotlin
- iOS/Swift
data class Identity(
val identityId: String,
val partyId: String,
val tenantId: String,
val identityRole: IdentityRole,
val isDefault: Boolean,
val createdAt: Instant,
val updatedAt: Instant,
val deletedAt: Instant?
)
struct Identity {
let identityId: String
let partyId: String
let tenantId: String
let identityRole: IdentityRole
let isDefault: Bool
let createdAt: Date
let updatedAt: Date
let deletedAt: Date?
}
Identity Roles
Identity roles define how an identity participates in credential flows:
- Android/Kotlin
- iOS/Swift
// Built-in identity roles
val issuer = IdentityRole.ISSUER // Issues credentials (OID4VCI)
val verifier = IdentityRole.VERIFIER // Requests/verifies credentials (OID4VP)
val holder = IdentityRole.HOLDER // Holds and presents credentials
// Custom roles
val registrar = IdentityRole("REGISTRAR")
val trustAnchor = IdentityRole("TRUST_ANCHOR")
// Built-in identity roles
let issuer = IdentityRole.issuer // Issues credentials (OID4VCI)
let verifier = IdentityRole.verifier // Requests/verifies credentials (OID4VP)
let holder = IdentityRole.holder // Holds and presents credentials
// Custom roles
let registrar = IdentityRole(value: "REGISTRAR")
let trustAnchor = IdentityRole(value: "TRUST_ANCHOR")
Tenant
A tenant provides organizational isolation:
- Android/Kotlin
- iOS/Swift
data class Tenant(
val tenantId: String,
val tenantType: TenantType,
val name: String,
val description: String?,
val ownerPartyId: String?,
val createdAt: Instant,
val updatedAt: Instant,
val deletedAt: Instant?
)
struct Tenant {
let tenantId: String
let tenantType: TenantType
let name: String
let description: String?
let ownerPartyId: String?
let createdAt: Date
let updatedAt: Date
let deletedAt: Date?
}
Tenant Types
- Android/Kotlin
- iOS/Swift
// Built-in tenant types
val orgTenant = TenantType.ORGANIZATION
val personTenant = TenantType.NATURAL_PERSON
// Custom types
val departmentTenant = TenantType("DEPARTMENT")
// Built-in tenant types
let orgTenant = TenantType.organization
let personTenant = TenantType.naturalPerson
// Custom types
let departmentTenant = TenantType(value: "DEPARTMENT")
Correlation Identifier
Links external identifiers to identities:
- Android/Kotlin
- iOS/Swift
data class CorrelationIdentifier(
val correlationId: String,
val identityId: String,
val tenantId: String,
val identifierType: IdentifierType,
val value: String,
val isPrimary: Boolean,
val isVerified: Boolean,
val validFrom: Instant?,
val validUntil: Instant?,
val createdAt: Instant,
val updatedAt: Instant,
val deletedAt: Instant?
)
struct CorrelationIdentifier {
let correlationId: String
let identityId: String
let tenantId: String
let identifierType: IdentifierType
let value: String
let isPrimary: Bool
let isVerified: Bool
let validFrom: Date?
let validUntil: Date?
let createdAt: Date
let updatedAt: Date
let deletedAt: Date?
}
Identifier Types
Types of external identifiers that can be correlated:
- Android/Kotlin
- iOS/Swift
// Built-in identifier types
val didIdentifier = IdentifierType.DID // W3C Decentralized Identifier
val x509Identifier = IdentifierType.X509 // X.509 Certificate
// Custom identifier types
val vatNumber = IdentifierType("VAT")
val leiCode = IdentifierType("LEI")
val emailIdentifier = IdentifierType("EMAIL")
val phoneIdentifier = IdentifierType("PHONE")
// Built-in identifier types
let didIdentifier = IdentifierType.did // W3C Decentralized Identifier
let x509Identifier = IdentifierType.x509 // X.509 Certificate
// Custom identifier types
let vatNumber = IdentifierType(value: "VAT")
let leiCode = IdentifierType(value: "LEI")
let emailIdentifier = IdentifierType(value: "EMAIL")
let phoneIdentifier = IdentifierType(value: "PHONE")
Lookup Flow
The correlation identifier enables flexible lookup:
External Identifier Value
↓
Correlation Identifier (matches type + value)
↓
Identity (role in credential ecosystem)
↓
Party (the actual entity)
For example, to find who issued a credential:
- Extract the issuer DID from the credential
- Look up the correlation identifier with type=DID and value=the DID
- Get the identity from the correlation identifier
- Get the party from the identity
Query Filters
PartyFilter
Filter parties when querying:
- Android/Kotlin
- iOS/Swift
// Filter by type
val filter = PartyFilter.byType(PartyType.ORGANIZATION)
// Filter by multiple types
val multiFilter = PartyFilter.byTypes(
setOf(PartyType.ORGANIZATION, PartyType.NATURAL_PERSON)
)
// Filter by origin
val externalFilter = PartyFilter.byOrigin(PartyOrigin.EXTERNAL)
// Filter by display name (partial match)
val nameFilter = PartyFilter.byDisplayName("Acme")
// Filter by owner
val ownedFilter = PartyFilter.byOwner("owner-party-id")
// Filter for root parties (no owner)
val rootFilter = PartyFilter.rootParties()
// Filter by creation date
val recentFilter = PartyFilter.createdBetween(
from = Instant.now().minus(Duration.ofDays(7)),
to = Instant.now()
)
// Filter by type
let filter = PartyFilter.byType(type: .organization)
// Filter by multiple types
let multiFilter = PartyFilter.byTypes(types: [.organization, .naturalPerson])
// Filter by origin
let externalFilter = PartyFilter.byOrigin(origin: .external)
// Filter by display name (partial match)
let nameFilter = PartyFilter.byDisplayName(name: "Acme")
// Filter by owner
let ownedFilter = PartyFilter.byOwner(ownerId: "owner-party-id")
// Filter for root parties (no owner)
let rootFilter = PartyFilter.rootParties()
Fetch Options
Control which related data to include when fetching parties:
- Android/Kotlin
- iOS/Swift
// Minimal - party only
val minimal = PartyFetchOptions.MINIMAL
// Include owner party
val withOwner = PartyFetchOptions.WITH_OWNER
// Include identities
val withIdentities = PartyFetchOptions.WITH_IDENTITIES
// Include identities with their correlation identifiers
val withFullIdentities = PartyFetchOptions.WITH_FULL_IDENTITIES
// Everything
val full = PartyFetchOptions.FULL
// Custom options
val custom = PartyFetchOptions(
includeOwner = true,
includeIdentities = true,
identityOptions = IdentityFetchOptions(
includeCorrelationIdentifiers = true
)
)
// Minimal - party only
let minimal = PartyFetchOptions.minimal
// Include owner party
let withOwner = PartyFetchOptions.withOwner
// Include identities
let withIdentities = PartyFetchOptions.withIdentities
// Include identities with their correlation identifiers
let withFullIdentities = PartyFetchOptions.withFullIdentities
// Everything
let full = PartyFetchOptions.full
Input Models
Creating Parties
- Android/Kotlin
- iOS/Swift
val createInput = PartyCreateInput(
partyType = PartyType.ORGANIZATION,
origin = PartyOrigin.MANAGED,
displayName = "Acme Corporation",
uri = "https://acme.example.com",
ownerId = null // Root party
)
let createInput = PartyCreateInput(
partyType: .organization,
origin: .managed,
displayName: "Acme Corporation",
uri: "https://acme.example.com",
ownerId: nil // Root party
)
Updating Parties
- Android/Kotlin
- iOS/Swift
val updateInput = PartyUpdateInput(
displayName = "Acme Corp (Updated)",
uri = "https://new.acme.example.com",
ownerId = "new-owner-id"
)
let updateInput = PartyUpdateInput(
displayName: "Acme Corp (Updated)",
uri: "https://new.acme.example.com",
ownerId: "new-owner-id"
)
Result Models
Query operations return result models with associated data:
- Android/Kotlin
- iOS/Swift
data class PartyResult(
val party: Party,
val owner: Party?,
val identities: List<IdentityResult>?
)
data class IdentityResult(
val identity: Identity,
val correlationIdentifiers: List<CorrelationIdentifier>?
)
data class TenantResult(
val tenant: Tenant,
val ownerParty: Party?
)
struct PartyResult {
let party: Party
let owner: Party?
let identities: [IdentityResult]?
}
struct IdentityResult {
let identity: Identity
let correlationIdentifiers: [CorrelationIdentifier]?
}
struct TenantResult {
let tenant: Tenant
let ownerParty: Party?
}
Entity Relationships
Use Cases
Representing an Issuer
// Party for the issuing organization
val issuerParty = Party(
partyId = "party-gov-dmv",
tenantId = "tenant-123",
partyType = PartyType.ORGANIZATION,
origin = PartyOrigin.EXTERNAL,
displayName = "Department of Motor Vehicles",
uri = "https://dmv.gov.example.com",
// ...
)
// Identity for their issuer role
val issuerIdentity = Identity(
identityId = "identity-dmv-issuer",
partyId = "party-gov-dmv",
tenantId = "tenant-123",
identityRole = IdentityRole.ISSUER,
isDefault = true,
// ...
)
// Correlation identifier for their DID
val issuerDid = CorrelationIdentifier(
correlationId = "corr-dmv-did",
identityId = "identity-dmv-issuer",
tenantId = "tenant-123",
identifierType = IdentifierType.DID,
value = "did:web:dmv.gov.example.com",
isPrimary = true,
isVerified = true,
// ...
)
Representing a Wallet User
// Party for the user
val userParty = Party(
partyId = "party-user-alice",
tenantId = "tenant-123",
partyType = PartyType.NATURAL_PERSON,
origin = PartyOrigin.MANAGED,
displayName = "Alice",
// ...
)
// Identity for their holder role
val holderIdentity = Identity(
identityId = "identity-alice-holder",
partyId = "party-user-alice",
tenantId = "tenant-123",
identityRole = IdentityRole.HOLDER,
isDefault = true,
// ...
)