my own indieAuth provider! indiko.dunkirk.sh/docs
indieauth oauth2-server

docs: make the distinction between client types clearer

dunkirk.sh 03c6a5e5 d6f846b0

verified
+81 -9
+25 -3
README.md
··· 72 72 73 73 ## Usage 74 74 75 - ### Creating OAuth Apps 75 + ### Client Types 76 + 77 + Indiko supports two types of OAuth clients: 78 + 79 + #### Auto-registered Clients (IndieAuth) 80 + 81 + Any app can use Indiko without admin approval. On first authorization: 82 + - Use any valid URL as your `client_id` (e.g., `https://myapp.example.com`) 83 + - Indiko fetches metadata from your `client_id` URL 84 + - App is automatically registered 85 + - **MUST use PKCE** (code_verifier) for security 86 + - **No client secret** (public client) 87 + - Cannot use role-based access control 88 + 89 + This is perfect for IndieAuth-compatible apps and personal projects. 90 + 91 + #### Pre-registered Clients (OAuth 2.0 with Secrets) 92 + 93 + For apps requiring client secrets or role-based access control, admins can pre-register clients: 76 94 77 95 1. Go to `/admin/clients` 78 96 2. Click "Create OAuth Client" 79 97 3. Fill in: 80 - 81 98 - **Name** - Display name for your app 82 99 - **Logo URL** - (Optional) URL to app logo 83 100 - **Description** - (Optional) Brief description ··· 86 103 - **Default Role** - (Optional) Auto-assign this role on first auth 87 104 88 105 4. Save and copy the generated credentials: 89 - 90 106 - **Client ID** - Format: `ikc_xxxxxxxxxxxxxxxxxxxxx` 91 107 - **Client Secret** - Format: `iks_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` 92 108 93 109 > [!IMPORTANT] 94 110 > The client secret is only shown once! Save it securely. 111 + 112 + **Pre-registered clients:** 113 + - **MUST use both PKCE and client_secret** in token requests 114 + - Support role assignment for RBAC (Role-Based Access Control) 115 + - Admin-managed metadata and permissions 116 + - Generated client ID format: `ikc_` prefix 95 117 96 118 ### Using as an IndieAuth Provider 97 119
+44 -4
SPEC.md
··· 62 62 // TTL: 24 hours 63 63 ``` 64 64 65 - ### Apps (Auto-registered) 65 + ### Apps 66 + 67 + There are two types of OAuth clients in indiko: 68 + 69 + #### Auto-registered Apps (IndieAuth) 66 70 ``` 67 71 app:{client_id} -> { 68 - client_id: string, // e.g. "https://blog.kierank.dev" 72 + client_id: string, // e.g. "https://blog.kierank.dev" (any valid URL) 69 73 redirect_uris: string[], 74 + is_preregistered: 0, // indicates auto-registered 70 75 first_seen: timestamp, 71 76 last_used: timestamp, 72 - name?: string // optional, from client metadata 77 + name?: string, // optional, from client metadata 78 + logo_url?: string // optional, from client metadata 73 79 } 74 80 ``` 75 81 82 + **Features:** 83 + - Client ID is any valid URL per IndieAuth spec 84 + - No client secret (public client) 85 + - MUST use PKCE (code_verifier) 86 + - Automatically registered on first authorization 87 + - Metadata fetched from client_id URL 88 + - Cannot use role-based access control 89 + 90 + #### Pre-registered Apps (OAuth 2.0 with secrets) 91 + ``` 92 + app:{client_id} -> { 93 + client_id: string, // e.g. "ikc_xxxxxxxxxxxxxxxxxxxxx" (generated ID) 94 + redirect_uris: string[], 95 + is_preregistered: 1, // indicates pre-registered 96 + client_secret_hash: string, // SHA-256 hash of client secret 97 + available_roles?: string[], // optional list of allowed roles 98 + default_role?: string, // optional role auto-assigned on first auth 99 + first_seen: timestamp, 100 + last_used: timestamp, 101 + name?: string, 102 + logo_url?: string, 103 + description?: string 104 + } 105 + ``` 106 + 107 + **Features:** 108 + - Client ID format: `ikc_` + 21 character nanoid 109 + - Client secret format: `iks_` + 43 character nanoid (shown once on creation) 110 + - MUST use PKCE (code_verifier) AND client_secret 111 + - Supports role-based access control 112 + - Admin-managed metadata 113 + - Created via admin interface 114 + 76 115 ### User Permissions (Per-App) 77 116 ``` 78 - permission:{username}:{client_id} -> { 117 + permission:{user_id}:{client_id} -> { 79 118 scopes: string[], // e.g. ["profile", "email"] 119 + role?: string, // optional, only for pre-registered clients 80 120 granted_at: timestamp, 81 121 last_used: timestamp 82 122 }
+12 -2
src/html/docs.html
··· 1119 1119 <li>Automatically register the client for future use</li> 1120 1120 </ul> 1121 1121 <p> 1122 - Auto-registered clients <strong>must</strong> use PKCE for security and <strong>cannot</strong> use client secrets or role assignment. 1122 + Auto-registered clients: 1123 1123 </p> 1124 + <ul> 1125 + <li><strong>Client ID format:</strong> Any valid URL (e.g., <code>https://myapp.example.com</code>)</li> 1126 + <li><strong>Authentication:</strong> MUST use PKCE only (no client secret)</li> 1127 + <li><strong>Limitations:</strong> Cannot use client secrets or role assignment</li> 1128 + </ul> 1124 1129 1125 1130 <div class="info-box"> 1126 1131 <strong>Security:</strong> ··· 1131 1136 <p> 1132 1137 Admins can pre-register clients for advanced features. <strong>All pre-registered clients require a client secret and must also use PKCE.</strong> 1133 1138 </p> 1139 + <p> 1140 + Pre-registered clients: 1141 + </p> 1134 1142 <ul> 1135 - <li><strong>Client secret:</strong> Required for all pre-registered clients (used in token exchange alongside PKCE)</li> 1143 + <li><strong>Client ID format:</strong> Generated with <code>ikc_</code> prefix (e.g., <code>ikc_xxxxxxxxxxxxxxxxxxxxx</code>)</li> 1144 + <li><strong>Client secret format:</strong> Generated with <code>iks_</code> prefix (shown once on creation)</li> 1145 + <li><strong>Authentication:</strong> MUST use both PKCE AND client_secret in token requests</li> 1136 1146 <li><strong>Role assignment:</strong> Admins can assign per-user roles for RBAC</li> 1137 1147 <li><strong>Available roles:</strong> Define which roles can be assigned (enforces dropdown selection)</li> 1138 1148 <li><strong>Default role:</strong> Automatically assigned to users on first authorization</li>