Throughout the history of enterprise software and SaaS platforms, security breaches stemming from “hardcoded default credentials” have been recurring hazards. Many open-source platforms hardcode credentials like admin / 123456 into database seed scripts for onboarding convenience. When these systems are promoted to staging or internet-facing production environments, overlooked default accounts become primary attack vectors for supply-chain compromise and lateral privilege escalation.
BitzOrcas.Modern strictly enforces “Secure by Default and Zero-Trust” architecture. The seeding infrastructure forbids committing plaintext passwords to source control, implementing a Fail-Closed environment variable injection contract coupled with client-side RSA-OAEP asymmetric transport encryption and 404 anti-probing tenant isolation.
Account Topology & Secure Injection Architecture
The architecture isolates the tenant data plane from the host operational plane:
Privileged Super Administrator: admin / Admin@2026
The built-in super administrator seed (BuiltinIdentitySuperAdminSeedStep) is provisioned exclusively for local rapid onboarding. This step executes only in development environments for tenant 1000001:
- Username:
admin - Development Password:
Admin@2026 - Bound Roles:
SuperAdmin(automatically aggregates all module governance permissions across the platform, includingRootCrossTenantandTenantDataScope).
Production Override Precedence
In production environments, using the default password triggers a fatal startup failure. The engine evaluates administrator credentials according to the following precedence hierarchy:
Identity:SuperAdmin:Password Config Key > Parameters:demo-user-password > USER__ADMIN__PASSWORD Environment Variable > Terminate ProcessIf the runtime detects HostingEnvironment == Production without an explicit credential override, the seed process aborts with an unrecoverable security exception.
The Seeded Account Matrix: Fail-Closed Password Injection
Aside from the development super administrator, all tenant and host accounts in seed CSV assets store environment variable reference placeholders (e.g., from-env:USER__OPERATOR__PASSWORD).
1. Injection Specifications and Hierarchical Mapping
The resolver accepts plaintext strings for dynamic hashing as well as pre-computed BCrypt hashes:
| Environment Variable | Payload | Runtime Behavior |
|---|---|---|
USER__<NAME>__PASSWORD | Plaintext password | The seed engine computes a BCrypt hash (work factor 11) before persistence |
USER__<NAME>__PASSWORD_HASH | Pre-computed BCrypt digest | The seed engine persists the digest directly, bypassing runtime hashing |
2. Injection Workflow and Password Reset
Before invoking database seeding, inject account passwords in your terminal:
# Tenant 1000001 operational rolesexport USER__OPERATOR__PASSWORD='Operator@2026'export USER__SUPPORT__PASSWORD='Support@2026'export USER__AUDITOR__PASSWORD='Auditor@2026'
# Host operational rolesexport USER__HOST_ADMIN__PASSWORD='HostAdmin@2026'export USER__HOST_OPS__PASSWORD='HostOps@2026'- Fail-Closed Guarantee: If the seed runner identifies an account without a corresponding environment variable, it throws
InvalidOperationExceptionand logs the missing key name. No fallback placeholder passwords are ever inserted. - Incremental Password Reset: By default, existing database accounts retain their current password hash during subsequent seed runs. To forcefully reset existing demo passwords to current injected variables, set:
Terminal window export BITZORCAS_RESET_DEMO_PASSWORDS=true
Seeded Account Catalog & Roles
Tenant Data Plane: Demo Tenant (TenantId = 1000001)
| Account | Roles | Operational Domain & Access Boundary |
|---|---|---|
admin | tenant-admin + root-admin | Highest tenant administrator with full authority over cases, billing, and seats |
operator | operator | Core domain operator (e.g., LegalTech matter intake, contract creation, quota management) |
support | support-agent | Front-line support agent handling service tickets and customer chat interactions |
auditor | auditor | Compliance auditor possessing read-only inquiry and activity audit inspection privileges |
developer | developer | Sandbox engineer with OpenAPI access and diagnostic endpoint permissions |
Host Operational Plane: Host Partition (TenantId = 0)
The Host partition manages platform infrastructure and tenant provisioning, holding no tenant business data:
host-admin: Platform root administrator.host-ops: Operations engineer managing database backups, health probes, and cluster nodes.host-developer: Framework engineer maintaining platform plugins and module governance.
Authentication Handshake: RSA-OAEP Encryption & Anti-Replay
BitzOrcas rejects plaintext passwords across the network wire. Clients must fetch a temporary asymmetric public key and construct a timestamped anti-replay envelope before calling login:
End-to-End C# Integration Test
The following integration test verifies public key retrieval, RSA-OAEP encryption, and authentication using WebApplicationFactory:
using System.Net;using System.Net.Http.Json;using System.Security.Cryptography;using System.Text;using BitzOrcas.Identity.Contracts.Identity.Dtos;using Shouldly;using Xunit;
public sealed class AuthenticationAndTenancyIntegrationTests : IClassFixture<CustomWebApplicationFactory>{ private readonly HttpClient _client;
public AuthenticationAndTenancyIntegrationTests(CustomWebApplicationFactory factory) { _client = factory.CreateClient(); }
[Fact] public async Task Login_WithRsaOaepEncryptedPassword_ShouldSucceedAndIssueJwt() { // 1. Fetch current active RSA-OAEP public encryption key and identifier var keyResponse = await _client.GetFromJsonAsync<CipherPublicKeyResponse>("/api/auth/cipher-key"); keyResponse.ShouldNotBeNull(); keyResponse.PublicKeyPem.ShouldNotBeNullOrWhiteSpace();
// 2. Construct anti-replay payload: nonce|timestamp|password var nonce = Guid.NewGuid().ToString("N"); var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var rawPayload = $"{nonce}|{timestamp}|Admin@2026";
// 3. Encrypt payload via RSA-OAEP-SHA256 using server public key using var rsa = RSA.Create(); rsa.ImportFromPem(keyResponse.PublicKeyPem); var encryptedBytes = rsa.Encrypt(Encoding.UTF8.GetBytes(rawPayload), RSAEncryptionPadding.OaepSHA256); var base64EncryptedPassword = Convert.ToBase64String(encryptedBytes);
// 4. Dispatch login request var loginRequest = new LoginRequest( UserName: "admin", EncryptedPassword: base64EncryptedPassword, CipherKeyId: keyResponse.KeyId);
var loginResponse = await _client.PostAsJsonAsync("/api/auth/login", loginRequest);
// 5. Machine assertion: verify HTTP 200 OK and valid JWT access token loginResponse.StatusCode.ShouldBe(HttpStatusCode.OK); var tokenResult = await loginResponse.Content.ReadFromJsonAsync<TokenResponse>(); tokenResult.ShouldNotBeNull(); tokenResult.AccessToken.ShouldNotBeNullOrWhiteSpace(); }}Multi-Tenant Isolation: Why 404 Instead of 403
In multi-tenant security architecture, a subtle vulnerability is Resource ID Enumeration Probing.
If Tenant B attempts to read a legal matter (MATTER-10029) belonging to Tenant A:
- Flawed Pattern (HTTP 403 Forbidden): The system informs the client that access is denied. This inadvertently confirms that the resource ID exists within the database, enabling adversaries to infer business volumes or coordinate targeted reconnaissance.
- BitzOrcas Defense (HTTP 404 Not Found): In the persistence layer (SqlSugar / EF Core), the global tenant query filter appends
WHERE TenantId = CurrentTenant.Id. The SQL query returns zero matching rows. The repository handles this as an absent entity, returning a uniform404 Not Found.
Through this defense-in-depth architecture, BitzOrcas guarantees that multi-tenant isolation boundaries remain leak-proof in both demonstration and production environments.