EGP User Account Service#
System Description & Goals#
AccountService is a modern, developer-centric, multi-tenant user management platform built in Go. It provides a robust and scalable backend solution designed to handle the complexities of user identity, organizational structures, application management, and secure API access control, empowering developers to focus on their core application logic.The service offers flexible authentication methods: traditional email/password flows alongside seamless Web3 wallet authentication. The Web3 integration allows users to log in securely using their existing blockchain wallets (supporting EVM chains and Solana), enhancing security through server-side cryptographic signature verification against unique nonces, preventing replay attacks and offering a frictionless onboarding experience for the Web3 community.Critically, AccountService also functions as a central authentication and authorization provider for other backend services within a microservice architecture. It implements the standard JWKS (JSON Web Key Set) protocol to publish public keys securely. Authenticated users (via standard login) can use the Token Exchange endpoint to obtain short-lived, RSA-signed Service JWTs. These JWTs contain essential user identity and organizational context (organization_id
, roles
), targeted at a specific service (audience
). This allows downstream services (e.g., NFT service, game servers) to independently verify a user's identity and permissions by validating the JWT signature against the public key obtained from the JWKS endpoint. This adherence to open standards (JWT, JWKS, RSA) promotes secure, decoupled inter-service communication without the need to share sensitive user session secrets across the infrastructure.Multi-Tenancy: Isolate data and management for different organizations (e.g., game studios, companies).
Flexible Authentication: Offer both traditional email/password login and modern, secure Web3 wallet-based authentication.
Inter-Service Auth (SSO Provider): Act as a trusted identity provider for other microservices using standard JWT/JWKS protocols, enabling secure, decoupled architectures.
Comprehensive Management: Provide robust tools for managing users, multi-tenant organizations, applications within those organizations, and API keys for direct server-to-server communication.
Scalability: Handle a growing number of users, organizations, and applications.
Developer Focus: Offer features essential for modern applications, including flexible authentication methods, role-based access control, API key management, and custom data storage.
User Self-Service: Empower end-users to manage their own profile information and credentials securely.
Flexibility: Support custom data fields associated with users within specific organizations.
Security: Implement standard authentication and authorization practices (HMAC JWTs for user sessions, API Keys, password hashing, nonce-based Web3 verification, RSA-signed Service JWTs for inter-service auth).
The system uses a RESTful API built with Go, backed by a PostgreSQL database, and emphasizes clear separation of concerns between user identity, organizational context, and application access.Implemented Features Highlights#
The following key features have been implemented based on the specification:Core User Authentication:User Registration (/auth/register
)
User Login with Email/Password (/auth/login
)
JWT Generation upon successful login.
JWT Validation Middleware (applied to protected routes).
Web3 Wallet Authentication:Login via wallet signature (Ethereum/EVM & Solana supported).
EVM Chains (Ethereum, Polygon, etc.): Uses EIP-4361 Sign-In with Ethereum (SIWE). The server provides a structured, human-readable message containing the domain, nonce, etc., which the user signs. This enhances security (phishing resistance) and user experience.
Solana: Uses a simple nonce signing mechanism for backward compatibility in direct authentication.
Server-side validation includes checking the domain, nonce, timestamps (for SIWE), and signature validity.
Nonce-based security mechanism prevents replay attacks across all chains.
Automatic user creation on first wallet login.
Support for multiple wallets linked to a single user account.
Why Web3 Auth? Security & Trust:
This method offers enhanced security and user control compared to traditional passwords. Instead of storing passwords, the server verifies cryptographic proof of ownership of a wallet address.EVM (SIWE): The user signs a unique, short-lived, domain-specific message provided by the server using their private key (which never leaves their wallet). The server verifies the signature against the full message, checking the domain, nonce, and other fields.
Solana: The user signs a unique, short-lived nonce provided by the server using their private key. The server verifies this signature against the nonce.
The single-use nonce prevents attackers from reusing old signatures (replay attacks).
This process ensures that only the true owner of the wallet can authenticate, without relying on server-side password storage.
Important Note on Verification: This signature verification process happens entirely off-chain using cryptographic principles.EVM (SIWE): The server uses the provided signature and the original SIWE message (which includes the nonce and domain context) to mathematically recover the public key and thus the address that signed the message. This validation includes checking the message structure and specific fields like domain and nonce against server expectations.
Solana: The server uses the signature and the known nonce to verify the signature using the user's public address (public key).
This verification does not require contacting the blockchain network via RPC, as it's purely a check of cryptographic proof, not blockchain state.
How Secure Is It? What Are the Risks?EVM (SIWE): Generally considered very secure when implemented correctly. Domain binding significantly enhances phishing resistance compared to simple nonce signing. Relies on standard, battle-tested cryptography (ECDSA for EVM).
Solana (Nonce): Secure against replay attacks due to the nonce, but less resistant to sophisticated phishing compared to SIWE because the signed message lacks domain context.
Overall: Private Key Security (key never leaves wallet), Proof of Ownership, Nonce Replay Prevention.
Create Organizations (Any authenticated user can create; creator becomes OWNER).
Get/Update Organization details (Requires Org Admin/Owner).
Middleware to parse OrgID from URL and ensure user membership.
Create Applications within an Organization (Requires Org Admin/Owner).
Get/Update/Delete Applications (Requires Org Admin/Owner of the App's Org).
Generate/List/Revoke API Keys for Applications (Requires Org Admin/Owner of the App's Org).
Keys are hashed in the database; raw key returned only on creation.
Organization Roles & Permissions:User-Organization linking (organization_users
table) with roles (MEMBER
, ADMIN
, OWNER
).
Middleware (MiddlewareCheckOrgRole
) to enforce role-based access on specific endpoints.
Listing/Updating/Removing organization members (Requires Org Admin/Owner).
is_super_admin
flag on the users
table.
Middleware (MiddlewareSuperAdmin
) to protect platform-level endpoints.
Endpoints for listing/suspending/activating organizations.
Get/Update organization-specific settings (login methods, password policy, etc.).
Permissions enforced (Members can GET, Admins/Owners can PUT).
Database store and helper function for logging events.
Endpoint stub to retrieve audit logs (Requires Org Admin/Owner).
User Analytics (Initial):Database store for user events.
Endpoint to receive events (/events
- Auth TBD, currently requires JWT).
Endpoint stub to retrieve basic analytics (Requires Org Admin/Owner).
custom_data
JSONB field added to organization_users
.
Store methods to get/update custom data using JSONB merge.
Handlers to get/set custom data for users within an org (permissions checked in handlers).
Handler and route for sending user invites to the organizaion via email.
Get User Profile (/users/me
)
Update User Profile (First/Last Name) (/users/me
)
Update User Password (/users/me/password
)
List user inventory items (/apps/{appId}/inventory
) with filtering and pagination
Create/update inventory items with versioned metadata
Role-based access control (Members can only see their own items, cannot modify)
Dual metadata structure: userMetadata (visible to owners) and systemMetadata (admin-only)
API Key support with inventory:read and inventory:write permissions
Inter-Service Authentication (JWT/JWKS/Token Exchange):Enables AccountService to act as an authentication provider for other backend services (e.g., NFT Service, Game Server).
Implements the standard JWKS (JSON Web Key Set) mechanism (/.well-known/jwks.json
) to securely publish the public RSA key used for signing service tokens.
Provides a Token Exchange endpoint (/api/v1/auth/token/exchange
) where a user, authenticated with their standard login JWT (HMAC-based), can request a new, short-lived JWT signed with the RSA key.
This new RSA JWT contains the user's ID and their roles within a specified organization, targeted for a specific audience (the receiving service).
Receiving services can validate these RSA JWTs independently using the public key fetched from the JWKS endpoint, without needing access to the AccountService's user session secrets (HMAC key).
Maintains backward compatibility with the existing HMAC JWT user authentication.
Requires RSA key pair stored securely (e.g., HashiCorp Vault) and relevant environment variables configured.
Web3 Single Sign-On (SSO) Flow (Phase 1 - EVM Only):Allows users to authenticate to third-party Relying Parties (RPs) using their Web3 wallet via the AccountService (acting as Identity Provider - IdP).
Currently supports EVM chains only.
Uses the EIP-4361 (SIWE) protocol for secure authentication at the IdP.
Issues an RSA-signed Service JWT upon success instead of an HMAC JWT.
Requires configuration of trusted RPs via environment variables.
Core Concept Relationships#
Understanding the relationship between Users, Organizations, Applications, and API Keys is crucial for using AccountService effectively:1.
Global Users: Users register (/auth/register
) and exist globally within the AccountService system. They are identified by a unique user_id
.
2.
Organizations: A user can create an Organization (/organizations
). This action makes that user the OWNER
of the new Organization. Organizations act as tenants, isolating resources.
3.
Membership & Roles: An OWNER
or ADMIN
of an Organization can add other existing global users as MEMBER
s or ADMIN
s to their specific Organization (/organizations/{orgId}/members
). A user's access within an organization is determined by their Role (OWNER, ADMIN, or MEMBER) in that specific organization.
4.
Applications: An OWNER
or ADMIN
can create Applications (/organizations/{orgId}/apps
) within their Organization. Applications represent your services or clients (e.g., a game client, a backend server).
5.
API Keys: An OWNER
or ADMIN
can generate API Keys (/apps/{appId}/apikeys
) for a specific Application. API Keys are credentials for server-to-server communication, tied directly to the Application (and thus its Organization). They are not tied to the user who created them.
6.
Authentication & Authorization:JWT (Bearer Token): When a user logs in (/auth/login
), they get a JWT. When using this JWT to access an endpoint related to an organization (e.g., /organizations/{orgId}/...
), the system checks the user's Role within that specific organization to grant or deny access.
API Key (X-API-Key Header): When an API Key is used, the system checks the Permissions assigned directly to that key (e.g., org:read
, app:create
) to grant or deny access. The key's permissions operate within the scope of the Organization that owns the Application the key belongs to. MEMBERS cannot generate API keys.
ADMIN/OWNER/API Key w/Perm)
(NOT by MEMBERs)Modified at 2025-05-03 01:44:59