Identity (TypeID)
How Authsome uses prefix-qualified, globally unique identifiers for every entity.
Every entity in Authsome has a TypeID. TypeIDs are globally unique, sortable, URL-safe identifiers built on UUIDv7 with a human-readable prefix that tells you what kind of entity you are looking at.
A TypeID looks like this:
ausr_01j9k3mq2fhex4vsk0n852p0qtThe ausr prefix identifies this as a user. The suffix is a base32-encoded UUIDv7 that encodes creation time, so IDs sort chronologically within the same prefix.
The id package
The id package in github.com/xraph/authsome/id provides the ID struct and type-specific named types built on top of it. All entity types share the same underlying struct — the prefix distinguishes them at parse time.
Creating IDs
import "github.com/xraph/authsome/id"
// Create a new ID for each entity type.
userID := id.NewUserID() // ausr_01j9...
sessionID := id.NewSessionID() // ases_01j9...
appID := id.NewAppID() // aapp_01j9...
orgID := id.NewOrganizationID() // aorg_01j9...
memberID := id.NewMemberID() // amem_01j9...
teamID := id.NewTeamID() // atm_01j9...
inviteID := id.NewInvitationID() // ainv_01j9...
deviceID := id.NewDeviceID() // adev_01j9...
webhookID := id.NewWebhookID() // awhk_01j9...
envID := id.NewEnvironmentID() // aenv_01j9...
roleID := id.NewRoleID() // arol_01j9...
permID := id.NewPermissionID() // aprm_01j9...Parsing IDs
// Parse any Authsome TypeID.
parsed, err := id.Parse("ausr_01j9k3mq2fhex4vsk0n852p0qt")
// Parse and validate a specific prefix.
userID, err := id.ParseUserID("ausr_01j9k3mq2fhex4vsk0n852p0qt")
sessID, err := id.ParseSessionID("ases_01j9k3mq2fhex4vsk0n852p0qt")
appID, err := id.ParseAppID("aapp_01j9k3mq2fhex4vsk0n852p0qt")Parsing with a prefix-specific function validates that the prefix matches. Passing a ausr_ ID to ParseSessionID returns an error — this prevents cross-entity ID confusion at the API boundary.
Nil ID
var empty id.UserID
empty.IsNil() // true
empty.String() // ""Nil IDs are the zero value for any named ID type. They serialize as empty strings in JSON.
String representation
userID := id.NewUserID()
fmt.Println(userID.String()) // "ausr_01j9k3mq2fhex4vsk0n852p0qt"
fmt.Println(userID.Prefix()) // "ausr"Database serialization
All ID types implement sql.Scanner and driver.Valuer. They store as plain strings in the database, and return NULL for nil IDs. No special column type is needed — use VARCHAR or TEXT.
JSON serialization
All ID types implement encoding.TextMarshaler and encoding.TextUnmarshaler. Nil IDs marshal as empty strings (""), not null.
Prefix reference
All 27 Authsome TypeID prefixes:
| Constant | Prefix | Entity |
|---|---|---|
id.PrefixUser | ausr | User account |
id.PrefixSession | ases | Auth session |
id.PrefixApp | aapp | Application |
id.PrefixOrganization | aorg | Organization |
id.PrefixMember | amem | Organization member |
id.PrefixTeam | atm | Team |
id.PrefixInvitation | ainv | Org invitation |
id.PrefixDevice | adev | Device |
id.PrefixWebhook | awhk | Webhook endpoint |
id.PrefixNotification | antf | Notification record |
id.PrefixVerification | avrf | Email/phone verification token |
id.PrefixPasswordReset | apwr | Password reset token |
id.PrefixAPIKey | akey | API key |
id.PrefixOAuthAccount | aoau | Linked OAuth account |
id.PrefixPasskey | apsk | Passkey credential |
id.PrefixMFADevice | amfa | MFA device (TOTP/SMS) |
id.PrefixEnvironment | aenv | Environment |
id.PrefixRole | arol | RBAC role |
id.PrefixPermission | aprm | RBAC permission |
id.PrefixRecoveryCode | arec | MFA recovery code |
id.PrefixSSOConnection | asso | SSO connection |
id.PrefixConsent | acns | OAuth2 consent record |
id.PrefixFormConfig | afcf | Dynamic form configuration |
id.PrefixBridge | abrd | Bridge configuration |
id.PrefixAppSessionConfig | ascf | Per-app session config |
id.PrefixOAuth2Client | ao2c | OAuth2 provider client |
id.PrefixAuditACO | aaco | Audit access control object |
Named ID types
Each entity has a named type alias over the base id.ID for additional compile-time safety:
type UserID = ID
type SessionID = ID
type AppID = ID
type OrganizationID = ID
type MemberID = ID
type TeamID = ID
type InvitationID = ID
type DeviceID = ID
type WebhookID = ID
type EnvironmentID = ID
type RoleID = ID
type PermissionID = ID
type MFADeviceID = ID
type PasskeyID = ID
type APIKeyID = IDUsing named types in function signatures makes intent explicit and prevents accidental misuse:
// Clear: the function wants a UserID, not just any ID.
func (e *Engine) GetMe(ctx context.Context, userID id.UserID) (*user.User, error)
// Clear: the function wants a SessionID specifically.
func (e *Engine) RevokeSession(ctx context.Context, sessionID id.SessionID) errorGenerating IDs from strings
When you have a raw string ID (e.g., from an HTTP header or database read), use the appropriate parse function:
rawUserID := r.Header.Get("X-User-ID") // "ausr_01j9..."
userID, err := id.ParseUserID(rawUserID)
if err != nil {
http.Error(w, "invalid user ID", http.StatusBadRequest)
return
}
u, err := engine.GetMe(ctx, userID)Using id.MustParse is available for contexts where you have already validated the format (e.g., in test setup):
userID := id.MustParse("ausr_01j9k3mq2fhex4vsk0n852p0qt")MustParse panics on invalid input. Never use it in production request handlers.