Move SSO clients from config to database
- Add sso_clients table (migration 000010) with client_id, redirect_uri, tags (JSON), enabled flag, and audit timestamps - Add SSOClient model struct and audit events - Implement DB CRUD with 10 unit tests - Add REST API: GET/POST/PATCH/DELETE /v1/sso/clients (policy-gated) - Add gRPC SSOClientService with 5 RPCs (admin-only) - Add mciasctl sso list/create/get/update/delete commands - Add web UI admin page at /sso-clients with HTMX create/toggle/delete - Migrate handleSSOAuthorize and handleSSOTokenExchange to use DB - Remove SSOConfig, SSOClient struct, lookup methods from config - Simplify: client_id = service_name for policy evaluation Security: - SSO client CRUD is admin-only (policy-gated REST, requireAdmin gRPC) - redirect_uri must use https:// (validated at DB layer) - Disabled clients are rejected at both authorize and token exchange - All mutations write audit events Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
web/templates/sso_clients.html
Normal file
53
web/templates/sso_clients.html
Normal file
@@ -0,0 +1,53 @@
|
||||
{{define "title"}} - SSO Clients{{end}}
|
||||
{{define "content"}}
|
||||
<div class="page-header d-flex justify-between align-center">
|
||||
<div>
|
||||
<h2>SSO Clients</h2>
|
||||
<p class="text-muted text-small">Registered applications that use MCIAS for single sign-on.</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="var f=document.getElementById('create-form');f.hidden=!f.hidden;this.textContent=f.hidden?'Add Client':'Cancel'">Add Client</button>
|
||||
</div>
|
||||
|
||||
<div id="create-form" class="card mt-2" hidden>
|
||||
<div class="card-title">Register SSO Client</div>
|
||||
<form hx-post="/sso-clients" hx-target="#sso-clients-tbody" hx-swap="afterbegin">
|
||||
<div class="d-flex gap-1" style="flex-wrap:wrap">
|
||||
<div class="form-group" style="flex:1;min-width:200px">
|
||||
<label class="form-label">Client ID / Service Name</label>
|
||||
<input class="form-control" type="text" name="client_id" required placeholder="e.g. mcr">
|
||||
</div>
|
||||
<div class="form-group" style="flex:2;min-width:300px">
|
||||
<label class="form-label">Redirect URI</label>
|
||||
<input class="form-control" type="url" name="redirect_uri" required placeholder="https://service.example.com/sso/callback">
|
||||
</div>
|
||||
<div class="form-group" style="flex:1;min-width:200px">
|
||||
<label class="form-label">Tags <span class="text-muted text-small">(comma-separated)</span></label>
|
||||
<input class="form-control" type="text" name="tags" placeholder="env:prod,tier:web">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-primary" type="submit">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client ID</th>
|
||||
<th>Redirect URI</th>
|
||||
<th>Tags</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="sso-clients-tbody">
|
||||
{{range .Clients}}
|
||||
{{template "sso_client_row" .}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{if not .Clients}}<p class="text-muted" style="text-align:center;padding:2rem">No SSO clients registered.</p>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user