403 lines
13 KiB
YAML
403 lines
13 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: TenantPilot System/Admin - Support Access Governance (Conceptual)
|
|
version: 0.1.0
|
|
description: |
|
|
Conceptual contract for the bounded workspace-scoped support-access package.
|
|
|
|
NOTE: These routes are implemented as existing Filament pages, resources,
|
|
and Livewire-backed actions. Exact Livewire payload shapes are not part of
|
|
this contract. The file captures logical route boundaries, plane separation,
|
|
approval flow, and the explicit rule that recovery requires both support
|
|
access and break-glass.
|
|
paths:
|
|
/directory/workspaces/{workspace}:
|
|
servers:
|
|
- url: /system
|
|
get:
|
|
summary: View current support-access posture for one workspace in the system plane
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceId'
|
|
responses:
|
|
'200':
|
|
description: System workspace detail rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/WorkspaceSupportAccessSummaryView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/directory/workspaces/{workspace}/actions/request-support-access:
|
|
servers:
|
|
- url: /system
|
|
post:
|
|
summary: Request bounded workspace-scoped support access from the system detail page
|
|
description: |
|
|
`audit_view` may activate immediately for an authorized platform actor.
|
|
|
|
`workspace_recovery` follows one of two logical branches:
|
|
- If the workspace still has at least one owner, the request becomes pending and must be approved from the admin workspace settings surface.
|
|
- If the workspace has zero owners, the request may only use the ownerless waiver branch when break-glass is already active and the caller supplies a distinct `waiver_reason`.
|
|
|
|
The ownerless waiver branch is blocked when break-glass is not active and is invalid when no waiver reason is supplied.
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RequestSupportAccessCommand'
|
|
responses:
|
|
'204':
|
|
description: Support-access request created or immediately activated
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
description: Active or pending grant already exists for the same workspace, actor, and scope, or ownerless recovery waiver prerequisites are blocked because break-glass is not active
|
|
'422':
|
|
$ref: '#/components/responses/ValidationError'
|
|
x-ownerless-waiver-preconditions:
|
|
applies_when:
|
|
scope: workspace_recovery
|
|
workspace_has_owners: false
|
|
requires:
|
|
- active_break_glass
|
|
- waiver_reason
|
|
failure_modes:
|
|
- status: 409
|
|
reason: ownerless waiver branch is blocked until break-glass is active
|
|
- status: 422
|
|
reason: ownerless waiver branch is invalid without a waiver reason
|
|
/directory/workspaces/{workspace}/support-access/{grant}/actions/end:
|
|
servers:
|
|
- url: /system
|
|
post:
|
|
summary: End an active support-access grant early
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceId'
|
|
- $ref: '#/components/parameters/GrantId'
|
|
responses:
|
|
'204':
|
|
description: Active support access ended successfully
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/settings/workspace:
|
|
servers:
|
|
- url: /admin
|
|
get:
|
|
summary: View pending recovery requests and the current support-access summary for the active workspace
|
|
responses:
|
|
'200':
|
|
description: Workspace settings support-access context rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/WorkspaceSupportApprovalView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/settings/workspace/support-access/{grant}/actions/approve:
|
|
servers:
|
|
- url: /admin
|
|
post:
|
|
summary: Approve a pending recovery-scoped support-access request from workspace settings
|
|
parameters:
|
|
- $ref: '#/components/parameters/GrantId'
|
|
responses:
|
|
'204':
|
|
description: Pending recovery request approved and activated
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
description: The request is no longer pending or no longer approvable in the current workspace context
|
|
/settings/workspace/support-access/{grant}/actions/deny:
|
|
servers:
|
|
- url: /admin
|
|
post:
|
|
summary: Deny a pending recovery-scoped support-access request from workspace settings
|
|
parameters:
|
|
- $ref: '#/components/parameters/GrantId'
|
|
responses:
|
|
'204':
|
|
description: Pending recovery request denied
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
description: The request is no longer pending or no longer denyable in the current workspace context
|
|
/audit-log:
|
|
servers:
|
|
- url: /admin
|
|
get:
|
|
summary: View support-access history through the existing workspace audit-log page
|
|
parameters:
|
|
- name: supportAccess
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: Audit log rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/SupportAccessAuditHistoryView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/audit-log/actions/export-support-access-history:
|
|
servers:
|
|
- url: /admin
|
|
post:
|
|
summary: Export support-access history for the active workspace
|
|
responses:
|
|
'202':
|
|
description: Export accepted or streamed according to the existing audit export pattern
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/repair-workspace-owners:
|
|
servers:
|
|
- url: /system
|
|
get:
|
|
summary: View the current recovery blocker state before attempting owner repair
|
|
responses:
|
|
'200':
|
|
description: Recovery utility page rendered with current prerequisite state
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/RecoveryBoundaryView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
/repair-workspace-owners/actions/assign-owner:
|
|
servers:
|
|
- url: /system
|
|
post:
|
|
summary: Execute owner repair only when both support access and break-glass are active
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AssignOwnerCommand'
|
|
responses:
|
|
'204':
|
|
description: Owner repair succeeded
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/BusinessStateBlocked'
|
|
/security/access-logs:
|
|
servers:
|
|
- url: /system
|
|
get:
|
|
summary: View system access logs including support-access events
|
|
responses:
|
|
'200':
|
|
description: Access-log page rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/SystemAccessLogView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
components:
|
|
parameters:
|
|
WorkspaceId:
|
|
name: workspace
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
GrantId:
|
|
name: grant
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
responses:
|
|
Forbidden:
|
|
description: Actor is in-scope but missing the required capability
|
|
NotFound:
|
|
description: Wrong plane, wrong workspace, or non-member access is hidden as not found
|
|
ValidationError:
|
|
description: Submitted support-access data is invalid for the requested scope or approval mode, including missing waiver detail for the ownerless recovery branch
|
|
BusinessStateBlocked:
|
|
description: Actor is otherwise authorized, but support-access state or break-glass state blocks the action
|
|
schemas:
|
|
RequestSupportAccessCommand:
|
|
type: object
|
|
required:
|
|
- scope
|
|
- reason
|
|
- ttl_minutes
|
|
properties:
|
|
scope:
|
|
type: string
|
|
enum:
|
|
- audit_view
|
|
- workspace_recovery
|
|
description: `workspace_recovery` may require owner approval or the explicit ownerless waiver branch.
|
|
reason:
|
|
type: string
|
|
ttl_minutes:
|
|
type: integer
|
|
waiver_reason:
|
|
type: string
|
|
nullable: true
|
|
description: Required only when `workspace_recovery` is requested for a workspace with zero owners and break-glass is already active.
|
|
AssignOwnerCommand:
|
|
type: object
|
|
required:
|
|
- workspace_id
|
|
- target_user_id
|
|
- reason
|
|
properties:
|
|
workspace_id:
|
|
type: integer
|
|
target_user_id:
|
|
type: integer
|
|
reason:
|
|
type: string
|
|
WorkspaceSupportAccessSummaryView:
|
|
type: object
|
|
properties:
|
|
workspace_id:
|
|
type: integer
|
|
active_grant_id:
|
|
type: integer
|
|
nullable: true
|
|
pending_grant_id:
|
|
type: integer
|
|
nullable: true
|
|
scope:
|
|
type: string
|
|
nullable: true
|
|
scope_label:
|
|
type: string
|
|
nullable: true
|
|
status:
|
|
type: string
|
|
requester_label:
|
|
type: string
|
|
nullable: true
|
|
reason:
|
|
type: string
|
|
nullable: true
|
|
approval_mode:
|
|
type: string
|
|
nullable: true
|
|
approver_label:
|
|
type: string
|
|
nullable: true
|
|
expires_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
needs_break_glass:
|
|
type: boolean
|
|
WorkspaceSupportApprovalView:
|
|
type: object
|
|
properties:
|
|
workspace_id:
|
|
type: integer
|
|
current_support_summary:
|
|
$ref: '#/components/schemas/WorkspaceSupportAccessSummaryView'
|
|
pending_recovery_requests:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PendingRecoveryRequestView'
|
|
PendingRecoveryRequestView:
|
|
type: object
|
|
properties:
|
|
grant_id:
|
|
type: integer
|
|
requester_label:
|
|
type: string
|
|
reason:
|
|
type: string
|
|
ttl_minutes:
|
|
type: integer
|
|
requested_at:
|
|
type: string
|
|
format: date-time
|
|
approval_mode:
|
|
type: string
|
|
waiver_reason:
|
|
type: string
|
|
nullable: true
|
|
SupportAccessAuditHistoryView:
|
|
type: object
|
|
properties:
|
|
workspace_id:
|
|
type: integer
|
|
support_access_filter_active:
|
|
type: boolean
|
|
export_available:
|
|
type: boolean
|
|
SystemAccessLogView:
|
|
type: object
|
|
properties:
|
|
includes_platform_auth:
|
|
type: boolean
|
|
includes_break_glass:
|
|
type: boolean
|
|
includes_support_access:
|
|
type: boolean
|
|
RecoveryBoundaryView:
|
|
type: object
|
|
properties:
|
|
workspace_id:
|
|
type: integer
|
|
nullable: true
|
|
has_active_break_glass:
|
|
type: boolean
|
|
has_active_recovery_grant:
|
|
type: boolean
|
|
recovery_grant_id:
|
|
type: integer
|
|
nullable: true
|
|
recovery_grant_expires_at:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
approver_label:
|
|
type: string
|
|
nullable: true
|
|
blocker_state:
|
|
type: string
|
|
blocker_message:
|
|
type: string
|
|
nullable: true
|