import { useState } from 'react'; import { SshGlobalConnectionsForm } from './SshGlobalConnectionsForm'; import { SshGrantsForm } from './SshGrantsForm'; import { SshMasterKeyRotationForm } from './SshMasterKeyRotationForm'; import { SshAuditLog } from './SshAuditLog'; import { SshConfigForm } from './SshConfigForm'; import type { SectionFormProps } from './types'; type SubTab = 'config' | 'connections' | 'grants' | 'rotation' | 'audit'; const TABS: { id: SubTab; label: string }[] = [ { id: 'config', label: 'Config' }, { id: 'connections', label: 'Global connections' }, { id: 'grants', label: 'Grants' }, { id: 'rotation', label: 'Rotation' }, { id: 'audit', label: 'Audit log' }, ]; interface Props extends SectionFormProps { showToast?: (msg: string, variant?: 'success' | 'error') => void; } /** * Admin SSH panel — 5 sub-tabs: * - config: ssh.* + ssh.console.* config.yaml editor (uses the parent * draft / save-bar flow via SectionFormProps) * - connections: global SSH connection registry (own per-row CRUD) * - grants: per-user / per-piece access grants (own CRUD) * - rotation: master encryption key rotation (own state machine) * - audit: ssh_audit_log viewer with prune action * * Sub-tab layout because the 5 concerns share no vertical space and have * very different shapes (form / lists / per-row CRUD / mode / table). */ export function SshForm({ config, onChange, overriddenByEnv, showToast }: Props) { const [tab, setTab] = useState('config'); return (

SSH 管理

グローバル SSH 設定 / 接続の登録 / アクセス権 (grants) / マスターキーローテーション / 監査ログ。 ユーザー個人の SSH 接続は User Folder →{' '} ssh-connections/ から管理します。

{tab === 'config' && } {tab === 'connections' && } {tab === 'grants' && } {tab === 'rotation' && } {tab === 'audit' && }
); }