feat: project native persona authorization status
This commit is contained in:
parent
584f38b478
commit
8f18c3fba3
38 changed files with 268 additions and 40 deletions
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git 证据",
|
||||
"hololake.personaRuntime.eventChain": "事件链头",
|
||||
"hololake.personaRuntime.attribution": "人类责任主体",
|
||||
"hololake.personaRuntime.readOnly": "只读投影 · 不触发执行动作"
|
||||
"hololake.personaRuntime.readOnly": "只读投影 · 不触发执行动作",
|
||||
"hololake.personaAuthorization.systemDirect": "系统直连 · 当前没有可信授权签名方",
|
||||
"hololake.personaAuthorization.unavailable": "授权状态不可核验 · 保持系统直连"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1169,5 +1169,7 @@
|
|||
"hololake.personaRuntime.gitHead": "Git evidence",
|
||||
"hololake.personaRuntime.eventChain": "Event chain head",
|
||||
"hololake.personaRuntime.attribution": "Human responsibility",
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action"
|
||||
"hololake.personaRuntime.readOnly": "Read-only projection · no execution action",
|
||||
"hololake.personaAuthorization.systemDirect": "System direct · no trusted authorization signer is registered",
|
||||
"hololake.personaAuthorization.unavailable": "Authorization status unverifiable · remaining system direct"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,22 @@ export type NativePersonaControlAuthorizationVerification = {
|
|||
authorizationEnabled: true
|
||||
}
|
||||
|
||||
export type PersonaControlAuthorizationStatus =
|
||||
| {
|
||||
phase: 'system_direct'
|
||||
reason: 'NO_TRUSTED_SIGNER'
|
||||
sourceCommit: string
|
||||
signerCount: 0
|
||||
authorizationEnabled: false
|
||||
}
|
||||
| {
|
||||
phase: 'unavailable'
|
||||
reason: string
|
||||
sourceCommit: null
|
||||
signerCount: 0
|
||||
authorizationEnabled: false
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
||||
}
|
||||
|
|
@ -62,3 +78,58 @@ export function hasPersonaPrimaryControlAuthorization(
|
|||
&& typeof signerId === 'string'
|
||||
&& /^[A-Z0-9][A-Z0-9._:@-]{1,159}$/.test(signerId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects only the currently published empty-trust registry state. A future
|
||||
* non-empty registry is not interpreted here because signer presence alone is
|
||||
* never persona-control authorization.
|
||||
*/
|
||||
export function parsePersonaControlAuthorizationStatus(
|
||||
receipt: unknown,
|
||||
): PersonaControlAuthorizationStatus {
|
||||
if (!isRecord(receipt) || Object.keys(receipt).length !== 5) {
|
||||
return unavailableStatus('REGISTRY_RECEIPT_INVALID')
|
||||
}
|
||||
const sourceCommit = Reflect.get(receipt, 'sourceCommit')
|
||||
if (
|
||||
exactString(receipt, 'status', 'CURRENT_EMPTY')
|
||||
&& Reflect.get(receipt, 'reason') === null
|
||||
&& typeof sourceCommit === 'string'
|
||||
&& /^[a-f0-9]{40}([a-f0-9]{24})?$/.test(sourceCommit)
|
||||
&& Reflect.get(receipt, 'signerCount') === 0
|
||||
&& Reflect.get(receipt, 'authorizationEnabled') === false
|
||||
) {
|
||||
return {
|
||||
phase: 'system_direct',
|
||||
reason: 'NO_TRUSTED_SIGNER',
|
||||
sourceCommit,
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
}
|
||||
}
|
||||
const reason = Reflect.get(receipt, 'reason')
|
||||
return unavailableStatus(typeof reason === 'string' && reason ? reason : 'REGISTRY_RECEIPT_INVALID')
|
||||
}
|
||||
|
||||
function unavailableStatus(reason: string): PersonaControlAuthorizationStatus {
|
||||
return {
|
||||
phase: 'unavailable',
|
||||
reason,
|
||||
sourceCommit: null,
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadPersonaControlAuthorizationStatus(): Promise<PersonaControlAuthorizationStatus> {
|
||||
try {
|
||||
const receipt = isTauri()
|
||||
? await invoke<unknown>('load_persona_control_authorization_registry')
|
||||
: await mockInvoke<unknown>('load_persona_control_authorization_registry')
|
||||
return parsePersonaControlAuthorizationStatus(receipt)
|
||||
} catch {
|
||||
return unavailableStatus('REGISTRY_UNAVAILABLE')
|
||||
}
|
||||
}
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { isTauri, mockInvoke } from '../mock-tauri'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
import { parsePersonaControlAuthorizationStatus } from './personaControlAuthorization'
|
||||
|
||||
const currentEmpty = {
|
||||
status: 'CURRENT_EMPTY',
|
||||
reason: null,
|
||||
sourceCommit: 'a'.repeat(40),
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
}
|
||||
|
||||
describe('persona-control authorization status projection', () => {
|
||||
it('projects only the exact native empty-trust receipt as system-direct', () => {
|
||||
expect(parsePersonaControlAuthorizationStatus(currentEmpty)).toEqual({
|
||||
phase: 'system_direct',
|
||||
reason: 'NO_TRUSTED_SIGNER',
|
||||
sourceCommit: 'a'.repeat(40),
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
['extra field', { ...currentEmpty, trusted: true }],
|
||||
['non-empty registry', { ...currentEmpty, status: 'CURRENT', signerCount: 1 }],
|
||||
['authorization enabled', { ...currentEmpty, authorizationEnabled: true }],
|
||||
['invalid commit', { ...currentEmpty, sourceCommit: 'main' }],
|
||||
])('fails closed for %s', (_label, receipt) => {
|
||||
expect(parsePersonaControlAuthorizationStatus(receipt)).toEqual({
|
||||
phase: 'unavailable',
|
||||
reason: 'REGISTRY_RECEIPT_INVALID',
|
||||
sourceCommit: null,
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('preserves a bounded native unavailable reason without creating authority', () => {
|
||||
expect(parsePersonaControlAuthorizationStatus({
|
||||
status: 'UNAVAILABLE',
|
||||
reason: 'ANCHOR_FETCH_FAILED',
|
||||
sourceCommit: null,
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
})).toEqual({
|
||||
phase: 'unavailable',
|
||||
reason: 'ANCHOR_FETCH_FAILED',
|
||||
sourceCommit: null,
|
||||
signerCount: 0,
|
||||
authorizationEnabled: false,
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Reference in a new issue