Releases: EmagjbyLabs/nythos
nythos-core v0.2.1
Summary
nythos-core v0.2.1 introduces the domain-level OAuth foundation for Nythos.
This release adds the core OAuth provider model, tenant-scoped external identities, tenant OAuth provider configuration, verified external profile boundaries, OAuth-specific ports, and decision-first OAuth login/linking orchestration.
The release keeps nythos-core infrastructure-free. Provider redirects, PKCE, authorization code exchange, token validation, JWKS fetching, userinfo calls, secrets, cookies, HTTP routes, and runtime/framework integration remain outside core.
Highlights
-
Added OAuth provider modeling:
- OAuthProviderKind
- Supported providers: Google, GitHub, Microsoft
- Stable lowercase persistence strings
- Parsing and display support
-
Added external identity domain modeling:
- ExternalIdentity
- Tenant-scoped provider identity links
- Natural key: (tenant_id, provider_kind, provider_subject)
- Provider email and display name metadata
- linked_at and last_seen_at timestamps
- Explicit touch(now) support for successful provider login tracking
-
Added tenant OAuth provider configuration:
- TenantOAuthProviderConfig
- Provider enabled/disabled flag
- Registration allowed/disallowed flag
- No secrets, client IDs, URLs, JWKS endpoints, redirect URIs, or provider HTTP configuration in core
-
Added verified external profile boundary:
- VerifiedExternalProfile
- Represents gateway-verified provider profile data
- verified_email() exposes email only when the provider has verified it
- Unverified email remains metadata only and is not safe for account-linking decisions
-
Added new OAuth ports:
- ExternalIdentityRepository
- TenantOAuthProviderConfigPort
-
Added OAuth login/linking orchestration:
- OAuthLoginService::resolve_login
- OAuthLoginService::link_identity
- OAuthLoginOutcome
-
Added explicit OAuth login outcomes:
- ProviderDisabled
- ExistingIdentityLogin
- LinkRequired
- RegistrationRequired
-
Added OAuth-specific error variants:
- OAuthIdentityAlreadyLinked
- OAuthIdentityAlreadyLinkedToSelf
- UserNotFoundOrInactive
-
Added tests for:
- OAuth domain models
- External identity repository contract
- Tenant OAuth provider config port contract
- OAuth login resolution
- Explicit external identity linking
- Public exports
- Error variants
-
Added documentation for the OAuth core/gateway boundary.
Why this changed
Nythos needs OAuth support without pulling provider mechanics into nythos-core.
OAuth itself requires infrastructure concerns: redirects, HTTP calls, token exchange, JWKS validation, PKCE, secrets, cookies, callback routes, and provider-specific behavior. Those belong in nythos-gateway or adapter layers.
This release gives core the domain model and decision boundary instead:
- Gateway verifies provider data.
- Gateway constructs VerifiedExternalProfile.
- Core resolves the tenant-scoped auth decision.
- Gateway decides how to complete UX, linking, registration, or session issuance.
This keeps the core crate clean, portable, testable, and runtime-agnostic.
Important behavior
OAuthLoginService::resolve_login is decision-first.
It does not:
- create users
- link identities
- issue sessions
- perform provider verification
- inspect unverified email
- cross tenant boundaries
It only returns the next domain outcome.
OAuthLoginService::link_identity is explicit.
It should be called only after gateway obtains user consent. It validates that the target user exists and can authenticate, checks for duplicate provider identity links, persists the external identity, and returns the linked identity.
Core/gateway boundary
nythos-core owns:
- OAuth provider domain types
- tenant OAuth provider configuration shape
- verified profile boundary type
- external identity domain model
- repository port contracts
- login/linking decisions
- account status checks
- tenant-scoped auth rules
nythos-gateway owns:
- OAuth redirects
- OAuth state / CSRF
- PKCE
- authorization code exchange
- provider token exchange
- provider ID token validation
- JWKS fetching
- provider userinfo fetching
- client secrets
- cookies
- HTTP routes
- framework/runtime integration
- database schema and migrations
- session issuance after core returns an outcome
- OAuth registration UX and completion
Compatibility
This is an additive patch release from 0.2.0 to 0.2.1.
- No existing public APIs were removed.
- No existing service constructors were changed.
- No existing port methods were changed.
- No runtime, framework, database, or OAuth provider dependencies were added.
- Existing email/password registration, login, refresh, revoke, session, and RBAC flows remain unchanged.
New public API surface
New domain types:
- OAuthProviderKind
- ExternalIdentity
- TenantOAuthProviderConfig
- VerifiedExternalProfile
New auth types:
- OAuthLoginOutcome
- OAuthLoginService
New ports:
- ExternalIdentityRepository
- TenantOAuthProviderConfigPort
New errors:
- OAuthIdentityAlreadyLinked
- OAuthIdentityAlreadyLinkedToSelf
- UserNotFoundOrInactive
nythos-core v0.2.0
Summary
nythos-core v0.2.0 adds the identity profile and login identifier foundation.
This release introduces optional username and display-name support, tenant-policy-gated profile fields, and identifier-based login while keeping email/password accounts intact and preserving the core crate’s infrastructure-free boundary.
OAuth is not part of this release.
Highlights
Added new domain value objects:
Username
DisplayName
LoginIdentifier
Added typed tenant auth policy:
TenantAuthPolicy
username_registration_enabled
display_name_registration_enabled
username_login_enabled
Added TenantPolicyPort for loading tenant auth policy inside core services.
Extended User with optional profile fields:
username: Option<Username>
display_name: Option<DisplayName>
Extended NewUser with optional profile fields while preserving NewUser::new(email).
Extended RegisterInput with optional raw profile input:
username: Option<String>
display_name: Option<String>
Updated RegisterService to enforce tenant profile policy:
username registration is accepted only when enabled
display-name registration is accepted only when enabled
duplicate username checks are tenant-scoped
email/password registration still works with default policy when no profile fields are supplied
Moved LoginInput toward identifier-based login:
preserved LoginInput::new(..., email: String, ...)
added LoginInput::new_with_identifier(...)
added identifier()
preserved email() as a compatibility alias
Updated LoginService to support LoginIdentifier:
email login uses find_credentials_by_email
username login uses find_credentials_by_username only when enabled
disabled username login returns InvalidCredentials
username credential lookup is not called when username login is disabled
Evolved UserRepository with username lookup methods:
find_by_username
find_credentials_by_username
Added ADR 0006 documenting login identifiers and optional profile fields.
Updated README and core docs for v0.2.0 behavior.
Why this changed
Nythos needs a foundation for richer identity profiles and future product-facing login options without weakening the core auth boundary.
Email remains the required credential identity for email/password accounts. Username and display name are optional profile fields. Username-based login is available only when a tenant explicitly enables it through TenantAuthPolicy.
This release keeps policy decisions visible in the service layer. Services parse LoginIdentifier, load tenant auth policy through TenantPolicyPort, and then call explicit repository methods. Repositories resolve concrete lookup keys only.
This avoids a vague find_credentials_by_identifier-style repository method where parsing, policy checks, and lookup behavior would be hidden behind one swampy abstraction.
Security behavior
Username login is disabled by default.
When username login is disabled, LoginService returns AuthError::InvalidCredentials and does not call username credential lookup.
The following cases intentionally collapse to the same public error:
username login disabled
username not found
wrong password
This prevents callers from using login responses to discover whether username login is enabled or whether a tenant-scoped username exists.
Breaking API shape changes
This release includes public API shape changes for port implementors and service constructors.
UserRepository implementors must now implement:
async fn find_by_username(
&self,
tenant_id: TenantId,
username: &Username,
) -> NythosResult<Option>;
async fn find_credentials_by_username(
&self,
tenant_id: TenantId,
username: &Username,
) -> NythosResult<Option>;
RegisterService::new now requires a TenantPolicyPort dependency.
LoginService::new now requires a TenantPolicyPort dependency.
Example:
let register_service = RegisterService::new(
&user_repository,
&tenant_policy_port,
&session_store,
&password_hasher,
&token_signer,
);
let login_service = LoginService::new(
&user_repository,
&role_repository,
&tenant_policy_port,
&session_store,
&password_hasher,
&token_signer,
);
Compatibility notes
Email/password registration still works with the default tenant auth policy when no optional profile fields are supplied.
LoginInput::new(..., email: String, ...) is preserved.
LoginInput::email() is preserved as a compatibility alias returning the raw identifier string.
LoginInput::new_with_identifier(...) is available for email-or-username login input.
User::new(...) and User::with_status(...) are preserved and set optional profile fields to None.
NewUser::new(email) is preserved and sets optional profile fields to None.
TenantSettings remains available, but it is not used for auth policy decisions.
TenantAuthPolicy defaults all optional profile and username-login features to false.
No HTTP, database, gateway, worker, OAuth, Cloudflare, or concrete crypto dependency was added to nythos-core.
Service structs remain borrow-oriented and continue taking dependencies by reference.
nythos-core v0.1.2
Summary
nythos-core v0.1.2 updates the core auth boundary from synchronous ports to native async ports.
This release unblocks async infrastructure adapters, especially Cloudflare Workers D1, without introducing runtime, database, HTTP, or Cloudflare-specific dependencies into the core crate.
Highlights
-
Converted core port traits to async:
UserRepositoryRoleRepositorySessionStorePasswordHasherTokenSignerRevocationChecker
-
Converted auth orchestration services to async:
RegisterService::registerLoginService::loginRefreshService::refreshRevokeSessionService::revokeRevokeAllSessionsService::revoke_all
-
Updated internal auth helpers to await async port calls.
-
Added ADR 0005 documenting the async core port decision.
-
Updated test fakes and orchestration tests for async execution.
Why this changed
The previous synchronous port shape blocked natural implementations for async infrastructure. Cloudflare Workers D1 APIs are async, so gateway adapters could not implement core repository/session traits cleanly without fake blocking behavior.
This release makes the core async-native while keeping it infrastructure-free and runtime-agnostic.
Breaking API shape change
This is a public API shape change for consumers implementing or calling core ports/services.
Trait implementations now use async fn, and service flow calls must be awaited.
Example:
let result = login_service.login(input).await?;Compatibility notes
- No HTTP, database, Cloudflare, or async runtime dependency was added to nythos-core.
- Domain models and value objects remain unchanged.
- Service structs remain borrow-oriented and continue taking dependencies by reference.
nythos-core v0.1.1
Fixed
- Added a
wasmfeature that enablesuuid/jsso UUID v4 generation works onwasm32-unknown-unknowntargets such as Cloudflare Workers.
nythos-core v0.1.0
Summary
nythos-core v0.1.0 is the first public release of the Nythos core authentication and authorization library.
This release establishes the infrastructure-free Rust core for Nythos, including domain primitives, identity models, auth/session/RBAC concepts, core orchestration services, and pure trait contracts for outer infrastructure layers.
Highlights
- Published
nythos-coreas a public Rust crate. - Added a strict core-only architecture with no HTTP, database, cache, queue, provider, or deployment-specific code.
- Introduced typed ID newtypes over
Uuid:UserIdTenantIdSessionIdRoleId
- Added validated domain value objects:
EmailPassword
- Added identity models:
UserUserStatusTenantTenantSettings
- Added auth/token models:
PasswordHashAccessTokenClaimsTokenPurpose
- Added session and refresh-token models:
SessionRefreshToken
- Added tenant-scoped RBAC models:
PermissionRoleRoleAssignmentRoleRegistry
- Added core auth orchestration services:
RegisterServiceLoginServiceRefreshServiceRevokeSessionServiceRevokeAllSessionsService
- Added pure infrastructure boundary ports:
UserRepositoryRoleRepositorySessionStorePasswordHasherTokenSignerRevocationChecker
- Added mandatory refresh-token rotation semantics.
- Added tenant-scoped RBAC rules with no global admin concept in core.
- Added a crate-wide
AuthErrorandNythosResult. - Added reference documentation under
docs/. - Added ADRs for core boundaries, single-crate start, tenant-scoped RBAC, and refresh-token rotation.
- Added integration-style tests using in-memory fakes for repository, session, token, password, and revocation ports.
Architecture
nythos-core is intentionally infrastructure-free.
The crate owns:
- domain types and invariants
- auth, session, and RBAC business rules
- orchestration logic for register, login, refresh, and revocation flows
- trait contracts for storage, signing, hashing, role lookup, and revocation checking
The crate does not own:
- HTTP handlers or status-code mapping
- database drivers, ORM models, SQL, or migrations
- Redis/cache adapters
- queues or event buses
- email/SMS/OAuth provider integrations
- concrete password hashing or token signing implementations
- product-specific gateway behavior
Outer layers are expected to implement the provided ports.
Core Flows
Register
Registration validates email/password input, checks tenant-scoped duplicate users, hashes the password through PasswordHasher, creates the user through UserRepository, and can optionally issue session auth material.
Login
Login validates credentials, loads user credentials within a tenant, checks account status, verifies the password, loads tenant-scoped roles, creates a session, signs access claims, and returns auth material.
Refresh
Refresh resolves an opaque refresh token through SessionStore, rejects missing/revoked/expired sessions, reloads tenant-scoped roles, signs fresh access claims, and rotates the refresh token.
Revoke Session
Single-session revocation checks current revocation state and revokes the session through SessionStore.
Revoke All Sessions
Revoke-all invalidates all sessions for a user within a tenant boundary.
Known Design Notes
Claimscurrently include subject, tenant, token purpose, issued-at, and expiry timestamps.Claimsdo not currently includeSessionId.- Because
RevocationCheckeroperates onSessionId, request-time revocation cannot be driven from verifiedClaimsalone yet. - This gap is documented and intentionally deferred past
v0.1.0.
Install
[dependencies]
nythos-core = "0.1.0"