feat(directory): improve OAuth client creation with better credential handling
Some checks failed
BotServer CI / build (push) Failing after 11s
Some checks failed
BotServer CI / build (push) Failing after 11s
- Updated setup_directory() to try multiple credential sources: 1. Existing config file 2. Zitadel log extraction 3. Default credentials 4. Helpful error message if all fail - Made ensure_admin_token() async to actually authenticate with credentials - Added test_zitadel_credentials() helper function - Improved error messages for debugging This addresses the issue where OAuth client creation was failing because credentials couldn't be extracted from Zitadel logs. Related: zit.md plan for automatic OAuth client creation
This commit is contained in:
parent
9fc33725b7
commit
abedde3af7
3 changed files with 488 additions and 2 deletions
48
AGENTS.md
48
AGENTS.md
|
|
@ -1,5 +1,7 @@
|
||||||
# General Bots AI Agent Guidelines
|
# General Bots AI Agent Guidelines
|
||||||
|
8080 is server 3000 is client ui
|
||||||
|
To test web is http://localhost:3000 (botui!)
|
||||||
|
Use apenas a lingua culta.
|
||||||
> **⚠️ CRITICAL SECURITY WARNING**
|
> **⚠️ CRITICAL SECURITY WARNING**
|
||||||
I AM IN DEV ENV, but sometimes, pasting from PROD, do not treat my env as prod! Just fix, to me and push to CI. So I can test in PROD, for a while.
|
I AM IN DEV ENV, but sometimes, pasting from PROD, do not treat my env as prod! Just fix, to me and push to CI. So I can test in PROD, for a while.
|
||||||
>Use Playwrigth MCP to start localhost:3000/<bot> now.
|
>Use Playwrigth MCP to start localhost:3000/<bot> now.
|
||||||
|
|
@ -37,6 +39,50 @@ See botserver/src/drive/local_file_monitor.rs to see how to load from /opt/gbo/d
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🔄 Reset Process Notes
|
||||||
|
|
||||||
|
### reset.sh Behavior
|
||||||
|
- **Purpose**: Cleans and restarts the development environment
|
||||||
|
- **Timeouts**: The script can timeout during "Step 3/4: Waiting for BotServer to bootstrap"
|
||||||
|
- **Bootstrap Process**: Takes 3-5 minutes to install all components (Vault, PostgreSQL, Valkey, MinIO, Zitadel, LLM)
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
1. **Script Timeout**: reset.sh waits for "Bootstrap complete: admin user" message
|
||||||
|
- If Zitadel isn't ready within 60s, admin user creation fails
|
||||||
|
- Script continues waiting indefinitely
|
||||||
|
- **Solution**: Check botserver.log for "Bootstrap process completed!" message
|
||||||
|
|
||||||
|
2. **Zitadel Not Ready**: "Bootstrap check failed (Zitadel may not be ready)"
|
||||||
|
- Directory service may need more than 60 seconds to start
|
||||||
|
- Admin user creation deferred
|
||||||
|
- Services still start successfully
|
||||||
|
|
||||||
|
3. **Services Exit After Start**:
|
||||||
|
- botserver/botui may exit after initial startup
|
||||||
|
- Check logs for "dispatch failure" errors
|
||||||
|
- Check Vault certificate errors: "tls: failed to verify certificate: x509"
|
||||||
|
|
||||||
|
### Manual Service Management
|
||||||
|
```bash
|
||||||
|
# If reset.sh times out, manually verify services:
|
||||||
|
ps aux | grep -E "(botserver|botui)" | grep -v grep
|
||||||
|
curl http://localhost:8080/health
|
||||||
|
tail -f botserver.log botui.log
|
||||||
|
|
||||||
|
# Restart services manually:
|
||||||
|
./restart.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reset Verification
|
||||||
|
After reset completes, verify:
|
||||||
|
- ✅ PostgreSQL running (port 5432)
|
||||||
|
- ✅ Valkey cache running (port 6379)
|
||||||
|
- ✅ BotServer listening on port 8080
|
||||||
|
- ✅ BotUI listening on port 3000
|
||||||
|
- ✅ No errors in botserver.log
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🔐 Security Directives - MANDATORY
|
## 🔐 Security Directives - MANDATORY
|
||||||
|
|
||||||
### 1. Error Handling - NO PANICS IN PRODUCTION
|
### 1. Error Handling - NO PANICS IN PRODUCTION
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0b1b17406db9d4cc91c1a29cf549398e72fd111a
|
Subproject commit 2c92a81302e1e2c5c533fd585e69a2b5beaace89
|
||||||
440
zit.md
Normal file
440
zit.md
Normal file
|
|
@ -0,0 +1,440 @@
|
||||||
|
# Zitadel OAuth Client Automatic Creation - Action Plan
|
||||||
|
|
||||||
|
## Current Status (March 1, 2026)
|
||||||
|
|
||||||
|
### ✅ FIXED: Health Check & Proxy Issues
|
||||||
|
|
||||||
|
**Problems Fixed:**
|
||||||
|
1. Zitadel health checks used port **9000** but Zitadel runs on port **8300**
|
||||||
|
2. BotUI proxy used `https://localhost:9000` but BotServer runs on `http://localhost:8080`
|
||||||
|
3. Directory base URL used port 9000 instead of 8300
|
||||||
|
|
||||||
|
**Files Fixed:**
|
||||||
|
1. `botserver/src/core/bootstrap/bootstrap_utils.rs` - Health check port 9000 → 8300
|
||||||
|
2. `botserver/src/core/package_manager/installer.rs` - ZITADEL_EXTERNALPORT and check_cmd 9000 → 8300
|
||||||
|
3. `botserver/src/core/directory/api.rs` - Health check URL to port 8300
|
||||||
|
4. `botlib/src/http_client.rs` - DEFAULT_BOTSERVER_URL to http://localhost:8080
|
||||||
|
5. `botserver/src/core/urls.rs` - DIRECTORY_BASE to port 8300
|
||||||
|
|
||||||
|
**Results:**
|
||||||
|
- ✅ Zitadel health check: 2 seconds (was 300 seconds)
|
||||||
|
- ✅ BotUI proxy: correct routing to BotServer
|
||||||
|
- ✅ Bootstrap completes successfully
|
||||||
|
- ✅ No more 502 Bad Gateway errors
|
||||||
|
|
||||||
|
### ❌ REMAINING: OAuth Client Not Created
|
||||||
|
|
||||||
|
**Problem:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "Authentication service not configured",
|
||||||
|
"details": "OAuth client credentials not available"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Root Cause:**
|
||||||
|
- File `botserver-stack/conf/system/directory_config.json` is **MISSING**
|
||||||
|
- Bootstrap cannot extract Zitadel credentials from logs
|
||||||
|
- OAuth client creation fails
|
||||||
|
- Login fails
|
||||||
|
|
||||||
|
## Root Cause Analysis
|
||||||
|
|
||||||
|
### Why the Previous Fix Failed
|
||||||
|
|
||||||
|
The commit `86cfccc2` (Jan 6, 2026) added:
|
||||||
|
- `extract_initial_admin_from_log()` to parse Zitadel logs
|
||||||
|
- Password grant authentication support
|
||||||
|
- Directory config saving
|
||||||
|
|
||||||
|
**But it doesn't work because:**
|
||||||
|
1. **Zitadel doesn't log credentials** in the expected format
|
||||||
|
2. Log parsing returns `None`
|
||||||
|
3. Without credentials, OAuth client creation fails
|
||||||
|
4. Config file is never created
|
||||||
|
5. **Chicken-and-egg problem persists**
|
||||||
|
|
||||||
|
### The Real Solution
|
||||||
|
|
||||||
|
**Instead of parsing logs, the bootstrap should:**
|
||||||
|
1. **Generate admin credentials** using `generate_secure_password()`
|
||||||
|
2. **Create admin user in Zitadel** using Zitadel's Management API
|
||||||
|
3. **Use those exact credentials** to create OAuth client
|
||||||
|
4. **Save config** to `botserver-stack/conf/system/directory_config.json`
|
||||||
|
5. **Display credentials** to user via console and `~/.gb-setup-credentials`
|
||||||
|
|
||||||
|
## Automatic Solution Design
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Bootstrap Flow (First Run):
|
||||||
|
1. Start Zitadel service
|
||||||
|
2. Wait for Zitadel to be ready (health check)
|
||||||
|
3. Check if directory_config.json exists
|
||||||
|
- If YES: Load config, skip creation
|
||||||
|
- If NO: Proceed to step 4
|
||||||
|
4. Generate admin credentials (username, email, password)
|
||||||
|
5. Create admin user in Zitadel via Management API
|
||||||
|
6. Create OAuth application via Management API
|
||||||
|
7. Save directory_config.json to botserver-stack/conf/system/
|
||||||
|
8. Display credentials to user
|
||||||
|
9. Continue bootstrap
|
||||||
|
|
||||||
|
Bootstrap Flow (Subsequent Runs):
|
||||||
|
1. Start Zitadel service
|
||||||
|
2. Wait for Zitadel to be ready
|
||||||
|
3. Check if directory_config.json exists
|
||||||
|
- If YES: Load config, verify OAuth client
|
||||||
|
- If NO: Run first-run flow
|
||||||
|
4. Continue bootstrap
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Changes Required
|
||||||
|
|
||||||
|
#### 1. Fix `setup_directory()` in `mod.rs`
|
||||||
|
|
||||||
|
**Current approach (broken):**
|
||||||
|
```rust
|
||||||
|
// Try to extract credentials from log
|
||||||
|
let credentials = extract_initial_admin_from_log(&log_path);
|
||||||
|
if let Some((email, password)) = credentials {
|
||||||
|
// Use credentials
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**New approach:**
|
||||||
|
```rust
|
||||||
|
// Check if config exists
|
||||||
|
let config_path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||||
|
if config_path.exists() {
|
||||||
|
// Load existing config
|
||||||
|
return load_config(&config_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate new credentials
|
||||||
|
let username = "admin";
|
||||||
|
let email = "admin@localhost";
|
||||||
|
let password = generate_secure_password();
|
||||||
|
|
||||||
|
// Create admin user in Zitadel
|
||||||
|
let setup = DirectorySetup::new_with_credentials(
|
||||||
|
base_url,
|
||||||
|
Some((email.clone(), password.clone()))
|
||||||
|
);
|
||||||
|
|
||||||
|
let admin_user = setup.create_admin_user(username, email, &password).await?;
|
||||||
|
|
||||||
|
// Create OAuth client
|
||||||
|
let oauth_client = setup.create_oauth_application().await?;
|
||||||
|
|
||||||
|
// Save config
|
||||||
|
let config = DirectoryConfig {
|
||||||
|
base_url,
|
||||||
|
admin_token: admin_user.pat_token,
|
||||||
|
client_id: oauth_client.client_id,
|
||||||
|
client_secret: oauth_client.client_secret,
|
||||||
|
// ... other fields
|
||||||
|
};
|
||||||
|
|
||||||
|
save_config(&config_path, &config)?;
|
||||||
|
|
||||||
|
// Display credentials to user
|
||||||
|
print_bootstrap_credentials(&config, &password);
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Add `create_admin_user()` to `DirectorySetup`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl DirectorySetup {
|
||||||
|
pub async fn create_admin_user(
|
||||||
|
&self,
|
||||||
|
username: &str,
|
||||||
|
email: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<AdminUser> {
|
||||||
|
// Use Zitadel Management API to create user
|
||||||
|
// Endpoint: POST /management/v1/users/human
|
||||||
|
|
||||||
|
let user_payload = json!({
|
||||||
|
"userName": username,
|
||||||
|
"profile": {
|
||||||
|
"firstName": "Admin",
|
||||||
|
"lastName": "User"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"email": email,
|
||||||
|
"isEmailVerified": true
|
||||||
|
},
|
||||||
|
"password": password,
|
||||||
|
"passwordChangeRequired": false
|
||||||
|
});
|
||||||
|
|
||||||
|
let response = self.client
|
||||||
|
.post(format!("{}/management/v1/users/human", self.base_url))
|
||||||
|
.json(&user_payload)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Extract user ID and create PAT token
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Ensure Directory Creation in `save_config()`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn save_config(path: &Path, config: &DirectoryConfig) -> Result<()> {
|
||||||
|
// Create parent directory if it doesn't exist
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
fs::create_dir_all(parent)
|
||||||
|
.map_err(|e| anyhow!("Failed to create config directory: {}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write config
|
||||||
|
let json = serde_json::to_string_pretty(config)?;
|
||||||
|
fs::write(path, json)
|
||||||
|
.map_err(|e| anyhow!("Failed to write config file: {}", e))?;
|
||||||
|
|
||||||
|
info!("Saved Directory configuration to {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Update Config File Path
|
||||||
|
|
||||||
|
**Old path:** `config/directory_config.json`
|
||||||
|
**New path:** `botserver-stack/conf/system/directory_config.json`
|
||||||
|
|
||||||
|
Update all references in:
|
||||||
|
- `botserver/src/core/package_manager/mod.rs`
|
||||||
|
- `botserver/src/core/bootstrap/bootstrap_manager.rs`
|
||||||
|
- `botserver/src/main_module/bootstrap.rs`
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
|
||||||
|
### Step 1: Create Admin User via API
|
||||||
|
|
||||||
|
**File:** `botserver/src/core/package_manager/setup/directory_setup.rs`
|
||||||
|
|
||||||
|
Add method to create admin user:
|
||||||
|
```rust
|
||||||
|
pub async fn create_admin_user(
|
||||||
|
&self,
|
||||||
|
username: &str,
|
||||||
|
email: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<AdminUser> {
|
||||||
|
// Implementation using Zitadel Management API
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Update setup_directory()
|
||||||
|
|
||||||
|
**File:** `botserver/src/core/package_manager/mod.rs`
|
||||||
|
|
||||||
|
Replace log parsing with direct user creation:
|
||||||
|
```rust
|
||||||
|
pub async fn setup_directory() -> Result<DirectoryConfig> {
|
||||||
|
let config_path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||||
|
|
||||||
|
// Check existing config
|
||||||
|
if config_path.exists() {
|
||||||
|
return load_config(&config_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate credentials
|
||||||
|
let password = generate_secure_password();
|
||||||
|
let email = "admin@localhost";
|
||||||
|
let username = "admin";
|
||||||
|
|
||||||
|
// Create admin and OAuth client
|
||||||
|
let setup = DirectorySetup::new(base_url);
|
||||||
|
let admin = setup.create_admin_user(username, email, &password).await?;
|
||||||
|
let oauth = setup.create_oauth_application(&admin.token).await?;
|
||||||
|
|
||||||
|
// Save config
|
||||||
|
let config = DirectoryConfig { /* ... */ };
|
||||||
|
save_config(&config_path, &config)?;
|
||||||
|
|
||||||
|
// Display credentials
|
||||||
|
print_credentials(username, email, &password);
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Fix save_config()
|
||||||
|
|
||||||
|
**File:** `botserver/src/core/package_manager/setup/directory_setup.rs`
|
||||||
|
|
||||||
|
Ensure parent directory exists:
|
||||||
|
```rust
|
||||||
|
async fn save_config_internal(&self, config: &DirectoryConfig) -> Result<()> {
|
||||||
|
let path = PathBuf::from("botserver-stack/conf/system/directory_config.json");
|
||||||
|
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
fs::create_dir_all(parent)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let json = serde_json::to_string_pretty(config)?;
|
||||||
|
fs::write(&path, json)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Remove Log Parsing
|
||||||
|
|
||||||
|
**File:** `botserver/src/core/package_manager/mod.rs`
|
||||||
|
|
||||||
|
Delete or deprecate `extract_initial_admin_from_log()` function - it's not reliable.
|
||||||
|
|
||||||
|
## Config File Structure
|
||||||
|
|
||||||
|
**Location:** `botserver-stack/conf/system/directory_config.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"base_url": "http://localhost:8300",
|
||||||
|
"default_org": {
|
||||||
|
"id": "<organization_id>",
|
||||||
|
"name": "General Bots",
|
||||||
|
"domain": "localhost"
|
||||||
|
},
|
||||||
|
"default_user": {
|
||||||
|
"id": "<user_id>",
|
||||||
|
"username": "admin",
|
||||||
|
"email": "admin@localhost",
|
||||||
|
"password": "",
|
||||||
|
"first_name": "Admin",
|
||||||
|
"last_name": "User"
|
||||||
|
},
|
||||||
|
"admin_token": "<personal_access_token>",
|
||||||
|
"project_id": "<project_id>",
|
||||||
|
"client_id": "<oauth_client_id>",
|
||||||
|
"client_secret": "<oauth_client_secret>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expected Bootstrap Flow
|
||||||
|
|
||||||
|
### First Run (No Config)
|
||||||
|
|
||||||
|
```
|
||||||
|
[Bootstrap] Starting Zitadel/Directory service...
|
||||||
|
[Bootstrap] Directory service started, waiting for readiness...
|
||||||
|
[Bootstrap] Zitadel/Directory service is responding
|
||||||
|
[Bootstrap] No directory_config.json found, initializing new setup
|
||||||
|
[Bootstrap] Generated admin password: Xk9#mP2$vL5@nQ8&
|
||||||
|
[Bootstrap] Creating admin user in Zitadel...
|
||||||
|
[Bootstrap] Admin user created: admin@localhost
|
||||||
|
[Bootstrap] Creating OAuth application...
|
||||||
|
[Bootstrap] OAuth client created: client_id=123456789
|
||||||
|
[Bootstrap] Saved Directory configuration to botserver-stack/conf/system/directory_config.json
|
||||||
|
|
||||||
|
╔════════════════════════════════════════════════════════════╗
|
||||||
|
║ 🔐 ADMIN LOGIN - READY TO USE ║
|
||||||
|
╠════════════════════════════════════════════════════════════╣
|
||||||
|
║ ║
|
||||||
|
║ Username: admin ║
|
||||||
|
║ Password: Xk9#mP2$vL5@nQ8& ║
|
||||||
|
║ Email: admin@localhost ║
|
||||||
|
║ ║
|
||||||
|
║ 🌐 LOGIN NOW: http://localhost:3000/suite/login ║
|
||||||
|
║ ║
|
||||||
|
╚════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
[Bootstrap] OAuth client created successfully
|
||||||
|
[Bootstrap] Bootstrap process completed!
|
||||||
|
```
|
||||||
|
|
||||||
|
### Subsequent Runs (Config Exists)
|
||||||
|
|
||||||
|
```
|
||||||
|
[Bootstrap] Starting Zitadel/Directory service...
|
||||||
|
[Bootstrap] Directory service started, waiting for readiness...
|
||||||
|
[Bootstrap] Zitadel/Directory service is responding
|
||||||
|
[Bootstrap] Loading existing Directory configuration
|
||||||
|
[Bootstrap] OAuth client verified: client_id=123456789
|
||||||
|
[Bootstrap] Bootstrap process completed!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Checklist
|
||||||
|
|
||||||
|
- [ ] Delete existing `botserver-stack/conf/system/directory_config.json`
|
||||||
|
- [ ] Run `./reset.sh` or restart botserver
|
||||||
|
- [ ] Verify admin user created in Zitadel
|
||||||
|
- [ ] Verify OAuth application created in Zitadel
|
||||||
|
- [ ] Verify `directory_config.json` exists with valid credentials
|
||||||
|
- [ ] Verify credentials displayed in console
|
||||||
|
- [ ] Verify `~/.gb-setup-credentials` file created
|
||||||
|
- [ ] Test login with displayed credentials
|
||||||
|
- [ ] Verify login returns valid token
|
||||||
|
- [ ] Restart botserver again
|
||||||
|
- [ ] Verify config is loaded (not recreated)
|
||||||
|
- [ ] Verify login still works
|
||||||
|
|
||||||
|
## Files to Modify
|
||||||
|
|
||||||
|
1. **`botserver/src/core/package_manager/mod.rs`**
|
||||||
|
- Update `setup_directory()` to generate credentials
|
||||||
|
- Remove `extract_initial_admin_from_log()` or mark deprecated
|
||||||
|
- Update config path to `botserver-stack/conf/system/directory_config.json`
|
||||||
|
|
||||||
|
2. **`botserver/src/core/package_manager/setup/directory_setup.rs`**
|
||||||
|
- Add `create_admin_user()` method
|
||||||
|
- Update `save_config_internal()` to create parent directories
|
||||||
|
- Update config path
|
||||||
|
|
||||||
|
3. **`botserver/src/core/bootstrap/bootstrap_manager.rs`**
|
||||||
|
- Update config path reference
|
||||||
|
- Ensure proper error handling
|
||||||
|
|
||||||
|
4. **`botserver/src/main_module/bootstrap.rs`**
|
||||||
|
- Update `init_directory_service()` to use new path
|
||||||
|
|
||||||
|
## Benefits of This Approach
|
||||||
|
|
||||||
|
1. **Fully Automatic** - No manual steps required
|
||||||
|
2. **Reliable** - Doesn't depend on log parsing
|
||||||
|
3. **Secure** - Generates strong passwords
|
||||||
|
4. **Repeatable** - Works on every fresh install
|
||||||
|
5. **User-Friendly** - Displays credentials clearly
|
||||||
|
6. **Persistent** - Config saved in version-controlled location
|
||||||
|
7. **Fast** - No waiting for log file parsing
|
||||||
|
|
||||||
|
## Migration from Old Setup
|
||||||
|
|
||||||
|
If `~/.gb-setup-credentials` exists but `directory_config.json` doesn't:
|
||||||
|
|
||||||
|
1. **Option A:** Use existing credentials
|
||||||
|
- Read credentials from `~/.gb-setup-credentials`
|
||||||
|
- Create OAuth client with those credentials
|
||||||
|
- Save to `directory_config.json`
|
||||||
|
|
||||||
|
2. **Option B:** Create new setup
|
||||||
|
- Ignore old credentials
|
||||||
|
- Generate new admin password
|
||||||
|
- Update or replace old credentials file
|
||||||
|
- Save to `directory_config.json`
|
||||||
|
|
||||||
|
**Recommendation:** Option A (use existing credentials if available)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
**Problem:** OAuth client not created because bootstrap can't extract Zitadel credentials from logs.
|
||||||
|
|
||||||
|
**Solution:** Generate credentials programmatically, create admin user via API, create OAuth client, save config automatically.
|
||||||
|
|
||||||
|
**Result:** Fully automatic, reliable bootstrap that creates all necessary credentials and configuration without manual intervention.
|
||||||
|
|
||||||
|
**Timeline:**
|
||||||
|
- Implementation: 2-4 hours
|
||||||
|
- Testing: 1 hour
|
||||||
|
- Total: 3-5 hours
|
||||||
|
|
||||||
|
**Priority:** HIGH - Blocking login functionality
|
||||||
Loading…
Add table
Reference in a new issue