Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion pages/security.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const summary = [
area: 'Identity, access & tenancy',
anchor: 'access',
status: 'partial',
note: 'Org RBAC + row-level tenant isolation today; SSO / SAML / SCIM not yet.',
note: 'Org RBAC, row-level tenant isolation, and TOTP step-up protect platform administration; SSO / SAML / SCIM is not included.',
},
{
area: 'Release integrity',
Expand Down Expand Up @@ -943,6 +943,41 @@ export default function SecurityPage() {
isolated per organization rather than shared across
tenants.
</p>
<p>
Authenticator-app two-factor authentication is
available to every account and enforced for
platform administration. The platform-admin console
always requires both the server-side administrator
allowlist and a current two-factor session.
When a signed-in session needs this additional
assurance, Cloud asks for one current 6-digit code
and returns the user to the protected page after it
is accepted.
</p>
<p>
Enrollment also produces one-time recovery codes.
If an authenticator is lost, a recovery code removes
the inaccessible factors. Factor removal invalidates
active sessions, so Cloud explicitly returns through
sign-in and then to Security &amp; 2FA to enroll a
replacement. Recovery never grants the protected
session by itself.
</p>
<p>
The signed-in account menu keeps identity and
organization context visible. It provides Security
&amp; 2FA, organization switching when an account
belongs to more than one workspace, and an explicit
sign-out action. The{' '}
<a
href="https://docs.openadapt.ai/guides/account-security/"
className="text-accent underline"
>
account-security guide
</a>{' '}
covers enrollment, step-up, recovery, and account or
workspace switching.
</p>
<p>
What is <strong className="text-ink">not</strong>{' '}
yet available:{' '}
Expand Down
18 changes: 18 additions & 0 deletions tests/securityMfa.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const security = fs.readFileSync(path.join(root, 'pages/security.js'), 'utf8')

test('trust center describes the platform-admin MFA and account-menu contract', () => {
assert.match(security, /two-factor authentication is[\s\S]*enforced for[\s\S]*platform administration/i)
assert.match(security, /platform-admin console[\s\S]*server-side administrator[\s\S]*current two-factor session/i)
assert.match(security, /one current 6-digit code[\s\S]*returns the user to the protected page/i)
assert.match(security, /recovery code[\s\S]*invalidates[\s\S]*returns through[\s\S]*sign-in[\s\S]*Security[\s\S]*never grants[\s\S]*protected[\s\S]*session/i)
assert.match(security, /organization switching[\s\S]*explicit[\s\S]*sign-out action/i)
assert.match(security, /docs\.openadapt\.ai\/guides\/account-security/)
assert.doesNotMatch(security, /default policy also requires two-factor[\s\S]*organization owners/i)
})
Loading