// Package model defines the shared data types used throughout MCIAS. // These are pure data definitions with no external dependencies. package model import "time" // AccountType distinguishes human interactive accounts from non-interactive // service accounts. type AccountType string // AccountTypeHuman and AccountTypeSystem are the two valid account types. const ( AccountTypeHuman AccountType = "human" AccountTypeSystem AccountType = "system" ) // AccountStatus represents the lifecycle state of an account. type AccountStatus string // AccountStatusActive, AccountStatusInactive, and AccountStatusDeleted are // the valid account lifecycle states. const ( AccountStatusActive AccountStatus = "active" AccountStatusInactive AccountStatus = "inactive" AccountStatusDeleted AccountStatus = "deleted" ) // Account represents a user or service identity in MCIAS. // Fields containing credential material (PasswordHash, TOTPSecretEnc) are // never serialised into API responses — callers must explicitly omit them. type Account struct { CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at,omitempty"` UUID string `json:"id"` Username string `json:"username"` AccountType AccountType `json:"account_type"` Status AccountStatus `json:"status"` PasswordHash string `json:"-"` TOTPSecretEnc []byte `json:"-"` TOTPSecretNonce []byte `json:"-"` ID int64 `json:"-"` TOTPRequired bool `json:"totp_required"` } // Role is a string label assigned to an account to grant permissions. type Role struct { GrantedAt time.Time `json:"granted_at"` GrantedBy *int64 `json:"-"` Role string `json:"role"` ID int64 `json:"-"` AccountID int64 `json:"-"` } // TokenRecord tracks an issued JWT by its JTI for revocation purposes. // The raw token string is never stored — only the JTI identifier. type TokenRecord struct { ExpiresAt time.Time `json:"expires_at"` IssuedAt time.Time `json:"issued_at"` CreatedAt time.Time `json:"created_at"` RevokedAt *time.Time `json:"revoked_at,omitempty"` JTI string `json:"jti"` RevokeReason string `json:"revoke_reason,omitempty"` ID int64 `json:"-"` AccountID int64 `json:"-"` } // IsRevoked reports whether the token has been explicitly revoked. func (t *TokenRecord) IsRevoked() bool { return t.RevokedAt != nil } // IsExpired reports whether the token is past its expiry time. func (t *TokenRecord) IsExpired() bool { return time.Now().After(t.ExpiresAt) } // SystemToken represents the current active service token for a system account. type SystemToken struct { ExpiresAt time.Time `json:"expires_at"` CreatedAt time.Time `json:"created_at"` JTI string `json:"jti"` ID int64 `json:"-"` AccountID int64 `json:"-"` } // PGCredential holds Postgres connection details for a system account. // The password is encrypted at rest; PGPassword is only populated after // decryption and must never be logged or included in API responses. type PGCredential struct { CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` PGHost string `json:"host"` PGDatabase string `json:"database"` PGUsername string `json:"username"` PGPassword string `json:"-"` PGPasswordEnc []byte `json:"-"` PGPasswordNonce []byte `json:"-"` ID int64 `json:"-"` AccountID int64 `json:"-"` PGPort int `json:"port"` } // AuditEvent represents a single entry in the append-only audit log. // Details must never contain credential material (passwords, tokens, secrets). type AuditEvent struct { EventTime time.Time `json:"event_time"` ActorID *int64 `json:"-"` TargetID *int64 `json:"-"` EventType string `json:"event_type"` IPAddress string `json:"ip_address,omitempty"` Details string `json:"details,omitempty"` ID int64 `json:"id"` } // Audit event type constants — exhaustive list, enforced at write time. const ( EventLoginOK = "login_ok" EventLoginFail = "login_fail" EventLoginTOTPFail = "login_totp_fail" EventTokenIssued = "token_issued" EventTokenRenewed = "token_renewed" EventTokenRevoked = "token_revoked" EventTokenExpired = "token_expired" EventAccountCreated = "account_created" EventAccountUpdated = "account_updated" EventAccountDeleted = "account_deleted" EventRoleGranted = "role_granted" EventRoleRevoked = "role_revoked" EventTOTPEnrolled = "totp_enrolled" EventTOTPRemoved = "totp_removed" EventPGCredAccessed = "pgcred_accessed" EventPGCredUpdated = "pgcred_updated" //nolint:gosec // G101: audit event type string, not a credential )