···72727373## Usage
74747575-### Creating OAuth Apps
7575+### Client Types
7676+7777+Indiko supports two types of OAuth clients:
7878+7979+#### Auto-registered Clients (IndieAuth)
8080+8181+Any app can use Indiko without admin approval. On first authorization:
8282+- Use any valid URL as your `client_id` (e.g., `https://myapp.example.com`)
8383+- Indiko fetches metadata from your `client_id` URL
8484+- App is automatically registered
8585+- **MUST use PKCE** (code_verifier) for security
8686+- **No client secret** (public client)
8787+- Cannot use role-based access control
8888+8989+This is perfect for IndieAuth-compatible apps and personal projects.
9090+9191+#### Pre-registered Clients (OAuth 2.0 with Secrets)
9292+9393+For apps requiring client secrets or role-based access control, admins can pre-register clients:
769477951. Go to `/admin/clients`
78962. Click "Create OAuth Client"
79973. Fill in:
8080-8198 - **Name** - Display name for your app
8299 - **Logo URL** - (Optional) URL to app logo
83100 - **Description** - (Optional) Brief description
···86103 - **Default Role** - (Optional) Auto-assign this role on first auth
87104881054. Save and copy the generated credentials:
8989-90106 - **Client ID** - Format: `ikc_xxxxxxxxxxxxxxxxxxxxx`
91107 - **Client Secret** - Format: `iks_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
9210893109 > [!IMPORTANT]
94110 > The client secret is only shown once! Save it securely.
111111+112112+**Pre-registered clients:**
113113+- **MUST use both PKCE and client_secret** in token requests
114114+- Support role assignment for RBAC (Role-Based Access Control)
115115+- Admin-managed metadata and permissions
116116+- Generated client ID format: `ikc_` prefix
9511796118### Using as an IndieAuth Provider
97119
+44-4
SPEC.md
···6262// TTL: 24 hours
6363```
64646565-### Apps (Auto-registered)
6565+### Apps
6666+6767+There are two types of OAuth clients in indiko:
6868+6969+#### Auto-registered Apps (IndieAuth)
6670```
6771app:{client_id} -> {
6868- client_id: string, // e.g. "https://blog.kierank.dev"
7272+ client_id: string, // e.g. "https://blog.kierank.dev" (any valid URL)
6973 redirect_uris: string[],
7474+ is_preregistered: 0, // indicates auto-registered
7075 first_seen: timestamp,
7176 last_used: timestamp,
7272- name?: string // optional, from client metadata
7777+ name?: string, // optional, from client metadata
7878+ logo_url?: string // optional, from client metadata
7379}
7480```
75818282+**Features:**
8383+- Client ID is any valid URL per IndieAuth spec
8484+- No client secret (public client)
8585+- MUST use PKCE (code_verifier)
8686+- Automatically registered on first authorization
8787+- Metadata fetched from client_id URL
8888+- Cannot use role-based access control
8989+9090+#### Pre-registered Apps (OAuth 2.0 with secrets)
9191+```
9292+app:{client_id} -> {
9393+ client_id: string, // e.g. "ikc_xxxxxxxxxxxxxxxxxxxxx" (generated ID)
9494+ redirect_uris: string[],
9595+ is_preregistered: 1, // indicates pre-registered
9696+ client_secret_hash: string, // SHA-256 hash of client secret
9797+ available_roles?: string[], // optional list of allowed roles
9898+ default_role?: string, // optional role auto-assigned on first auth
9999+ first_seen: timestamp,
100100+ last_used: timestamp,
101101+ name?: string,
102102+ logo_url?: string,
103103+ description?: string
104104+}
105105+```
106106+107107+**Features:**
108108+- Client ID format: `ikc_` + 21 character nanoid
109109+- Client secret format: `iks_` + 43 character nanoid (shown once on creation)
110110+- MUST use PKCE (code_verifier) AND client_secret
111111+- Supports role-based access control
112112+- Admin-managed metadata
113113+- Created via admin interface
114114+76115### User Permissions (Per-App)
77116```
7878-permission:{username}:{client_id} -> {
117117+permission:{user_id}:{client_id} -> {
79118 scopes: string[], // e.g. ["profile", "email"]
119119+ role?: string, // optional, only for pre-registered clients
80120 granted_at: timestamp,
81121 last_used: timestamp
82122}
+12-2
src/html/docs.html
···11191119 <li>Automatically register the client for future use</li>
11201120 </ul>
11211121 <p>
11221122- Auto-registered clients <strong>must</strong> use PKCE for security and <strong>cannot</strong> use client secrets or role assignment.
11221122+ Auto-registered clients:
11231123 </p>
11241124+ <ul>
11251125+ <li><strong>Client ID format:</strong> Any valid URL (e.g., <code>https://myapp.example.com</code>)</li>
11261126+ <li><strong>Authentication:</strong> MUST use PKCE only (no client secret)</li>
11271127+ <li><strong>Limitations:</strong> Cannot use client secrets or role assignment</li>
11281128+ </ul>
1124112911251130 <div class="info-box">
11261131 <strong>Security:</strong>
···11311136 <p>
11321137 Admins can pre-register clients for advanced features. <strong>All pre-registered clients require a client secret and must also use PKCE.</strong>
11331138 </p>
11391139+ <p>
11401140+ Pre-registered clients:
11411141+ </p>
11341142 <ul>
11351135- <li><strong>Client secret:</strong> Required for all pre-registered clients (used in token exchange alongside PKCE)</li>
11431143+ <li><strong>Client ID format:</strong> Generated with <code>ikc_</code> prefix (e.g., <code>ikc_xxxxxxxxxxxxxxxxxxxxx</code>)</li>
11441144+ <li><strong>Client secret format:</strong> Generated with <code>iks_</code> prefix (shown once on creation)</li>
11451145+ <li><strong>Authentication:</strong> MUST use both PKCE AND client_secret in token requests</li>
11361146 <li><strong>Role assignment:</strong> Admins can assign per-user roles for RBAC</li>
11371147 <li><strong>Available roles:</strong> Define which roles can be assigned (enforces dropdown selection)</li>
11381148 <li><strong>Default role:</strong> Automatically assigned to users on first authorization</li>