Authsome

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_01j9k3mq2fhex4vsk0n852p0qt

The 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:

ConstantPrefixEntity
id.PrefixUserausrUser account
id.PrefixSessionasesAuth session
id.PrefixAppaappApplication
id.PrefixOrganizationaorgOrganization
id.PrefixMemberamemOrganization member
id.PrefixTeamatmTeam
id.PrefixInvitationainvOrg invitation
id.PrefixDeviceadevDevice
id.PrefixWebhookawhkWebhook endpoint
id.PrefixNotificationantfNotification record
id.PrefixVerificationavrfEmail/phone verification token
id.PrefixPasswordResetapwrPassword reset token
id.PrefixAPIKeyakeyAPI key
id.PrefixOAuthAccountaoauLinked OAuth account
id.PrefixPasskeyapskPasskey credential
id.PrefixMFADeviceamfaMFA device (TOTP/SMS)
id.PrefixEnvironmentaenvEnvironment
id.PrefixRolearolRBAC role
id.PrefixPermissionaprmRBAC permission
id.PrefixRecoveryCodearecMFA recovery code
id.PrefixSSOConnectionassoSSO connection
id.PrefixConsentacnsOAuth2 consent record
id.PrefixFormConfigafcfDynamic form configuration
id.PrefixBridgeabrdBridge configuration
id.PrefixAppSessionConfigascfPer-app session config
id.PrefixOAuth2Clientao2cOAuth2 provider client
id.PrefixAuditACOaacoAudit 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      = ID

Using 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) error

Generating 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.

On this page