Shared MCP Hub: user journeys, isolation and secrets UX
Status: requirements for review, not a claim of implemented or verified behavior. Scope updated November 4, 2026: publish the shared MCP Hub first. Daedro Secret is its credential-management subsystem, not a separate product the user must operate. Dedicated per-user MCP infrastructure is a later release.
Evidence reviewed: internal/secretsui/handler.go,
docs/connected-mcp-rollout.md, current owner screenshots and the recorded
setup failures. No new browser walkthrough was performed for this review.
Product promise
A person joins the Hub, chooses a profile and MCP, connects their account or credential in the interface, and gets a useful result. Their credentials, requests, uploads, jobs and results are inaccessible to other users. The MCP runtime can be shared; caller authorization and data cannot be shared implicitly.
Ordinary users never run scripts, install Python, handle OpenBao root/unseal material, restore IAP tunnels or remember an infrastructure-recovery passphrase. Authentication is browser-based. Device/passkey confirmation establishes the account session. In addition, every human secret operation requires a fresh, action-bound Google Authenticator confirmation. A login code is not reusable authority to manipulate secrets.
Use MCP Hub as the product entry, with Profiles, Connections, Activity and Settings. Put Credentials under a connection and in Settings for cross-connection management. Entering credential metadata requires a fresh authenticator confirmation for that explicit profile-scoped view. OpenBao appears only in administrator infrastructure diagnostics. Avoid making customers understand secret mounts, AppRoles or technical policy paths.
Domain vocabulary and boundaries
| Entity | Meaning | Authorization rule |
|---|---|---|
| Account | A verified human identity and security factors | Stable server identity; not an email string supplied with a request |
| Workspace | Tenant boundary for membership and owned resources | Default new account gets one personal workspace; no automatic access to another workspace |
| Profile | A named working context inside a workspace, such as Personal or Client A | Credentials, connections and results belong to an explicit profile; switching the UI cannot grant access |
| Catalog entry | Public metadata for an available MCP and its reviewed operations | Contains no tenant credentials, object inventory or private usage data |
| Connection | A profile-scoped binding to an MCP, provider account and allowed operations | Uses exactly the caller-authorized credential reference; not a global mutable active credential |
| Credential | Secret material stored server-side plus safe metadata | Exact workspace/profile/owner permissions; never returned to the client merely to invoke a tool |
| Browser session | Short-lived authentication context | Resolves server-side account and authorized workspace/profile; contains no provider key or OpenBao root token |
| Invocation/job | One authorized operation and its immutable caller context | Carries account/workspace/profile/connection binding across synchronous and background processing |
| Result/upload | Data produced or consumed by a job | Same isolation contract as its parent invocation; opaque IDs are not authorization |
A profile is not a physical server. Do not use a Private checkbox to imply a dedicated MCP instance in this release. If a sharing control is implemented, label it Only me or an exact set of permitted members. Dedicated runtime is a different feature and must be unavailable until its deployment works.
For initial public scope, recommend personal workspaces and profile isolation, without collaboration grants. Team sharing can be added explicitly later. Workspace administration must not silently mean permission to reveal all members' credentials or transcripts. Define that policy before implementing teams.
Main journey
1. Join and secure account
Entry: Get started from the public catalog.
Use the chosen verified account provider/invitation policy. Google sign-in, if selected for public account creation, is different from Google Authenticator: name the former Continue with Google, the latter Authenticator code. Do not imply that scanning a TOTP QR proves an email identity or grants a tenant.
Offer Create a passkey in the browser/OS sheet. Supporting copy: Use Touch ID, your device PIN, or a security key. Do not guarantee Touch ID on every device or invent an invisible password fallback. A public deployment must never assign installation administrator status to the first visitor.
Enroll Google Authenticator with an in-app QR and instructions:
Open Google Authenticator → Add account → Scan a QR code.
Secondary Can’t scan? reveals the setup key. Generate the QR locally;
never send the TOTP seed to an external QR image service or analytics.
One six-digit field supports paste and one-time-code autofill. Primary action:
Verify and continue. Account access requiring MFA is enabled only after a
valid code. Incorrect code retries stay on this screen; they do not erase a
completed passkey registration. Bound attempts and prevent OTP/challenge replay.
Do not replace one memorized password with a recovery-file password. Recommend a backup passkey and a tested recovery route. Recovery codes, if used, are one-time backup artifacts, not an extra normal-login password. Account recovery must not imply that inaccessible OpenBao encryption material can be decrypted.
2. Choose profile
Create the first profile automatically as Personal, avoiding a mandatory empty naming form. Show the current profile in the persistent application shell. Users can rename it or create another profile, such as Client A.
A profile switch changes the connections, credential references, recent jobs and results shown. It cancels or rebinds any unsubmitted operation safely. It never silently executes a form prepared under the previous profile. A submitted job keeps its original context even if the user changes profile while it runs.
Empty state: Connect your first MCP. Primary action: Browse MCPs.
3. Select MCP from the shared catalog
Categories should follow tasks: Data & storage, Audio & transcription, Video, Text & documents, Messaging & social, and Automation. Search by name or task. Do not duplicate an entry into a fake feature merely because a category needs content.
Each card shows name, task, supported operations, credential requirement, shared-service availability and charging information when known. Product badges must be concrete: Available, Setup required, Temporarily unavailable. Avoid an undifferentiated green Ready badge.
The detail page explains what data is sent to the provider, required access scope, limits, whether an action can change external data, and the actual supported runtime. Primary action: Connect. For unavailable services, show why and provide a real next action; never offer a nonfunctional launch button.
4. Connect securely
Connection form contains only provider-required fields. Prefer provider OAuth when supported; otherwise use a password-style credential field with a concise scope hint. A provider key is entered once. Display the target profile directly above the save action: Save to Personal.
If a caller already owns an authorized credential in this profile, offer Use an existing credential. Do not list another user's credential names or another profile's inventory without explicit authorization. A shared catalog entry must never default to the last credential another user supplied.
Primary action: Review and connect. A confirmation sheet shows the profile, connection, credential label and requested permissions, then asks for a fresh Google Authenticator code. The code approves exactly that displayed operation or explicit batch. The separate secret-module API stores the secret, grants the reviewed scope and returns a reference; the Hub stores that reference, not the credential. A harmless authenticated probe then returns a typed result. Retry is idempotent. A failed probe retains the secure record where appropriate and lets the owner replace it; it does not redisplay the secret value. A different existing value requires explicit update semantics.
Success: Connected to S3 with the account/connection metadata safe for that caller. Never claim Transcription tested after only a capabilities request.
Existing local MCP discovery is an operator migration facility, not a public user onboarding requirement. Publish the reviewed catalog; do not scan a customer's device, files or accounts without an explicit supported integration.
5. Perform a useful action
S3 first slice: Browse buckets → Browse objects → metadata/detail. Results include bounded authorized names, sizes and timestamps, with prefix filters and pagination. Return useful data, not only a generic successful-call message. Keep upload/delete unavailable until their operation and confirmation contracts are implemented.
Audio/video: Upload audio / Upload video, then supported provider/format options and Transcribe. Show upload limits and external-processing context before submission. Preserve a durable job across reload; show queued, running, completed and failed states. Completed means a readable transcript/result is available to the submitting principal, not merely that a job ID was returned. Video should reuse the existing voice service rather than duplicate speech provider credentials and behavior.
No arbitrary command, secret path, endpoint or tool name can be supplied by a browser caller. The server selects reviewed operations and validates typed arguments. Request IDs and opaque resource IDs are not access grants.
6. Results and activity
Activity is scoped to the current authorized profile. Each entry shows operation, connection, time, outcome, duration and a safe diagnostic reference. Show clear partial failures and retryability. Do not place prompts, secret fields, bearer headers, full transcripts or provider error bodies in general telemetry.
Share/export is a separate, explicit operation. Do not create public result links by default. Signed download URLs must be short-lived and scoped; possession of a job ID must not retrieve another caller's upload or result. Browser back/forward, cache and server rendering must not resurrect data after sign-out/profile change.
Secret-module contract: confirm every human change
This is a hard product requirement, not optional login step-up. The Secret module has its own API and authorization enforcement. Hub clients hold opaque references and safe status only. The Hub must not return provider secrets to callers or substitute its own session token for the required action confirmation.
| Human action | What the confirmation shows | Result |
|---|---|---|
| Enter credential metadata | Workspace/profile and the metadata view being opened | Scoped metadata access; no secret values |
| Add credential | Target profile, credential label, provider, initial usage grants | New reference/version; value never returned |
| Replace or rotate credential | Exact credential and current version, affected connections and new scope | Updated reference/version, safe outcome |
| Delete credential | Exact target and affected dependent connections | Safe deletion result; no secret returned |
| Grant or change MCP access | Credential reference, MCP/connection, permitted operations, duration/scope | Exact approved grant |
| Revoke access | Grant target and affected MCP/connection | Revoked grant/status |
UI confirmation copy: Confirm this change → action summary → Google Authenticator code → Confirm [specific action]. Do not prefill or replay a code from sign-in. Do not show a raw secret value in the confirmation summary. For add/replace, the browser submits the value securely but never receives it back from the API, including errors or completion responses. Reveal and export are unavailable in v1; do not ship disabled-looking reveal endpoints underneath.
The action challenge is bound server-side to actor, authenticated session, workspace/profile, credential/reference/version, action, requested scope and an expiry. A submitted OTP cannot approve a different body, changed target, later operation or wider scope. Challenges are one-use. A body/version change requires another review. Failed or canceled confirmation performs no mutation. Errors retain safe form context; secret values are not persisted in browser storage.
Reduce clicks by allowing an explicit batch such as “Store this S3 credential and grant this connection read-only bucket/object access.” Show every change and target before the code. One code approves exactly that atomic batch, not a timed period of unrestricted secret administration. If atomic execution cannot be provided, expose precise partial results and safe retry semantics instead of claiming all changes were applied.
Metadata entry confirmation is scoped to the displayed workspace/profile and view, with a short explicit validity/expiry policy. Switching profiles or requesting a different secret view must not reuse broader authority. Do not prompt separately for each label in one approved metadata listing; do not turn entry approval into indefinite global read permission.
An automatic MCP invocation does not ask for an OTP on every run. It can use only a previously TOTP-approved exact grant, with fresh short-lived workload access. Creating, widening, rotating or reassigning that grant is a new human secret action and requires confirmation. A manual “Run” of an already-authorized operation likewise cannot silently create a grant. The UI must distinguish Run operation from Allow this MCP to use a credential.
Shared runtime is not shared user state
The release specification must prohibit the following, including in adapters:
- Global
active_api_key, global current-profile state, or a reused authenticated MCP session changing credentials between simultaneous callers. - Result caches keyed only by operation/arguments without authorization context.
- Shared temporary filenames, uploads or working directories containing caller material, unless their ownership and access are explicitly isolated.
- Background jobs losing the original caller context, or workers reading secrets based only on untrusted payload workspace/profile fields.
- Cross-user listings, metadata leaks, error differences revealing foreign IDs, guessed download IDs, and support/admin dashboards returning user content by default.
The UX cannot compensate for an adapter that holds global credentials. Such an adapter remains unavailable in shared mode until it has request-scoped identity and isolated data, or an isolation mechanism appropriate for that adapter. Dedicated per-user infrastructure is later scope, but the first shared release still needs per-request/session/process isolation where the implementation requires it. “Shared server” is not permission to merge tenants.
Return login and recovery
Return login: Continue with a passkey → Authenticator code → previously permitted page. Avoid a username/password form when discoverable credentials and the selected identity provider support the intended flow. Keep the destination and safe draft context through re-authentication; do not replay writes silently.
Passkeys prove possession of a private key; MAC addresses, device names and hardware fingerprints are not equivalent authentication. Standard Apple passkeys can sync across devices. Label them Passkeys; My MacBook is a user label, not a cryptographically guaranteed single-device identity. Apple passkeys, Apple passkey security.
Choose the stable public HTTPS relying-party domain before public enrollment. Temporary IP-based pilot authentication must not be presented as portable public account enrollment.
| Loss scenario | Supported path |
|---|---|
| Device lost; another passkey exists | Other passkey plus TOTP; revoke the lost credential |
| Phone changed; Authenticator restored/transferred | Existing passkey plus restored code |
| TOTP lost; passkey remains | Previously issued single-use recovery code replaces TOTP for recovery, then fresh enrollment |
| All passkeys lost | Established account-recovery policy; never TOTP-only owner promotion |
| Both factors lost | Explicit account recovery with defined assurance; no silent tenant or data reset |
| Infrastructure encryption keys lost | Administrator data-recovery procedure; unrelated to changing user factors |
A single-owner pilot without an independent recovery administrator cannot claim complete recovery from a Mac-only Keychain copy. Do not force users to memorize another password to hide this architectural limitation. Define and test a backup route; communicate its boundary honestly. Google Authenticator transfer/sync.
Meaningful errors
| Condition | User message | Next action |
|---|---|---|
| Passkey canceled | Sign-in was canceled. | Try again |
| Wrong TOTP | That code did not match. Try the current code. | Remain on code screen |
| Session expired | Confirm it’s you to continue. | Passkey/TOTP, preserve safe context |
| Credential rejected | S3 rejected this credential. | Update credential |
| Permission absent | This credential cannot list buckets. | Bucket-scoped option if actually supported |
| Service offline | Audio service is temporarily unavailable. | Retry, plus truthful service status |
| Secret store reconnecting | The secure store is reconnecting. Your keys are unchanged. | Automatic bounded recovery, then Retry |
| Secret store needs recovery | The secure store needs administrator attention. | Status/support; never a member unseal-key form |
| Foreign/missing resource | This item is unavailable. | Return to authorized list, same response shape |
Do not expose URLError, PEM errors or shell instructions. Distinguish provider
permission failures from wrong login factors. Do not retain credential values in
DOM or fill them into an update form after an error.
Observability requirements
The public catalog may show aggregate availability of a shared MCP. It must not show another tenant's invocation count, private connection identifiers, provider account names, query details or output. User Activity is filtered server-side by account/workspace/profile. Operational traces use safe identifiers and structured error categories; their access is a separate administrator permission.
Existing observability capabilities need inventory before promising dashboards. A log file or an unscoped server-wide events page is not a tenant-safe Activity feature. Requirements must identify which current audit/log/metrics components exist and which are new work. Do not add fictional MCPs to fill this category.
First public release acceptance
Do not equate the current single-demo-workspace pilot with this contract. It has a narrow connection-check UI, static operator mapping, local bearer processors, serialized execution and manual infrastructure lifecycle. Its existing tests do not prove isolation for the shared public Hub.
Required acceptance gates:
- Every credential add/replace/delete/rotation/grant/revocation and metadata-view entry is rejected without its fresh action-bound TOTP confirmation. Test code replay, changed targets/bodies/versions, cross-profile substitution, canceled operations, expired challenges and explicit batch atomicity. Login MFA alone never authorizes these requests. Background runs work only under the previously approved grant. Reveal/export endpoints do not exist in v1.
- Two independently registered accounts create profiles and connections through the browser without scripts, manual certificate bypass or OpenBao knowledge.
- Both can sign out and return through the specified passkey/TOTP flow; canceled and invalid attempts recover in place and replay/cross-origin requests fail.
- A real S3 credential is stored through the subsystem, a real authorized API listing succeeds, and usable bounded results render without credential leaks.
- Account A cannot list/read/update/delete B's credentials, profiles, connections, uploads, jobs, activity or results by guessed IDs or changed request fields. Repeat within A's separate profiles according to policy.
- Concurrent A/B requests with distinct keys to the same shared MCP return only their own results. Check retries, cached responses, streaming, worker restarts, failures and browser profile switching, not only successful single calls.
- UI/server/job-store restart preserves ownership and saved connections. Secret store reconnection is internal; credential requests are not repeated to mask an infrastructure outage. Failed startup cannot assign a new owner.
- Real audio/video processing produces a durable authorized result before that catalog feature is marked verified. Capability discovery alone is insufficient.
- Observability and support surfaces do not expose cross-tenant data. Secrets remain absent from page source, logs, traces, command arguments and Git.
- Account/factor recovery is tested with a disposable account; storage recovery is tested separately. Factor reset never grants access to another tenant.
- Old source credentials/data remain intact until replacement reads and restart behavior pass; retirement is explicit. Dedicated runtime controls are absent or clearly unavailable until a later scoped release.
Smallest useful slice and rollout boundary
First implement and accept public identity + personal workspace/profile + one shared S3 connector + browser credential onboarding + real result browsing + two-user isolation + restart behavior. Keep all detected MCPs inventoried, with truthful availability. Then apply the same contracts to audio/video, other data adapters and operational surfaces. Do not expand eleven incomplete adapters in parallel while the first tenant-isolated user journey is still broken.
Visual direction: a readable glass shell with persistent profile context, compact authentication screens and a wider connections/results layout. Avoid putting an entire marketplace into a narrow centered sign-in form. Validate keyboard access, visible focus, 200% text zoom and a narrow viewport using the actual implemented flow.
Public approval is about this complete journey and its isolation evidence, not a pretty setup screenshot or unit-suite pass. The current user's previous setup failed repeatedly at Python, tunnel and recovery-passphrase steps; the replacement must remove those steps from the customer contract, not merely reword them.