Skip to content

Add reusable per-user integration connections #307

Closed as not planned
Closed as not planned

Description

@Medformatik

What problem would this solve?

Integration configuration is primarily instance-wide. Features that connect an individual user's account or data source currently need bespoke tables and services, making OAuth, secret storage, refresh, health, revocation, and account UI inconsistent.

What would you like to be able to do?

Add a generic end-user integration connection framework while keeping instance-level enablement and OAuth client configuration under administrator control. A connection should bind a user to an integration/provider account with encrypted credentials, declared scopes, refresh/revoke lifecycle, and privacy-safe health state.

Acceptance criteria

  • Manifests distinguish instance enablement/configuration, system OAuth client secrets, and end-user connection credentials.
  • A generic connection schema records user, integration, external subject, scopes, encrypted credential reference, status, timestamps, and metadata without plaintext secrets.
  • The framework supports OAuth authorization-code/PKCE and API-token style connections with provider-specific adapters.
  • Redirect/state/PKCE validation prevents CSRF, account-confusion, and redirect abuse.
  • Server request context gives integrations an authorized user connection without exposing credentials to the browser or unrelated integrations.
  • Refresh, expiry, re-consent, scope changes, revocation, provider errors, and account deletion have explicit lifecycle behavior.
  • Users can connect, inspect status/scopes, reconnect, and disconnect from account settings.
  • Admins can enable/disable a provider and configure the system client without seeing user tokens.
  • Logs, metrics, health checks, and support diagnostics are redacted and tenant/user scoped.
  • Authorization tests prevent cross-user connection lookup/use and confused-deputy requests.
  • A migration/adoption plan evaluates Dawarich and linked accounts without forcing a risky flag-day rewrite.
  • Developer documentation includes a reference provider and test harness.

Alternatives or workarounds

One custom table/service per provider is initially quick but duplicates security-sensitive lifecycle code. Making all integration config user-scoped would incorrectly expose deployment-level settings.

Additional context

Reported starting point

  • integration_config is unique per integration and serves administrator-managed settings.
  • Better Auth has linked OSM/Mapillary accounts.
  • Dawarich uses a dedicated personal_timeline_connection and encrypted credential flow.
  • Integration manifests can declare credentialOwner: end-user, but the framework does not operationalize a generic per-user connection lifecycle.
  • Document user-data trust boundaries and decide the E2EE architecture #312 is complete. The accepted confidentiality architecture classifies provider credentials needed by the server as server-required secrets, encrypted with a server-held key when plaintext use is required. This provides the trust-model baseline for this framework; general user-data E2EE is not implemented.

Area

Integration framework, authentication, secret storage, account settings, API.

Dependencies

The trust-model decision in #312 is complete, so it is no longer an unresolved design prerequisite. Credential and connected-data handling must follow docs/docs/developer/user-data-confidentiality-architecture.md and docs/docs/developer/user-data-trust-model.md. Future client encryption remains subject to the accepted architecture's design and security-review gates; it is not implied by encrypted provider-token storage.

Activity

  1. changed the title [-]Create a generic end-user integration connection framework[/-] [+]Add reusable per-user integration connections[/+] on Oct 18, 2026
  2. Medformatik commented on Nov 1, 2026

    @Medformatik
    CollaboratorAuthor

    Closing as not planned after a backlog review.

    • The only server-side per-user credential today is the Dawarich timeline connection (apps/api/src/db/timeline-connection-schema.ts), and it works.
    • The only other credentialOwner: "end-user" integration is reviews-mangrove, which uses a client-held keypair, not OAuth.
    • A generic OAuth/PKCE connection framework with lifecycle, redirect-abuse and confused-deputy handling isn't justified by one consumer.

    Extract the shared framework when a second real server-side per-user provider actually lands. Reopen then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions