Skip to content

feat: add secure OAuth connection core - #179

Merged
mohanagy merged 2 commits into
developmentfrom
feat/81-oauth-connection-core
Jul 22, 2026
Merged

feat: add secure OAuth connection core#179
mohanagy merged 2 commits into
developmentfrom
feat/81-oauth-connection-core

Conversation

@mohanagy

@mohanagy mohanagy commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Closes #81\n\n## What changed\n\n- introduces configuration version 3 with profile-bound OAuth connection records that contain opaque oauthconn references only\n- binds each record to the exact profile, upstream, canonical HTTPS resource, issuer, client registration, and scope set\n- stores credential envelopes only in the native operating-system credential vault and keeps non-secret metadata in a restrictive atomic registry\n- serializes connect, refresh, and disconnect lifecycles with single-flight refresh, cancellation, timeout, compensation, and redacted audit events\n- keeps version 1 and version 2 non-OAuth configuration compatible\n- fails closed with OAUTH_AUTHORIZATION_NOT_ENABLED when a version 3 OAuth connection is configured before the authorization engine is available\n- rejects static Authorization headers when an OAuth connection is configured\n\n## Boundary\n\nThis PR is the secure connection and credential-lifecycle core only. Browser launch, callback handling, provider discovery, token exchange, refresh over the network, and upstream header injection remain intentionally out of scope for #81 and will be implemented by the dependent OAuth roadmap issues.\n\n## Validation\n\n- focused OAuth tests: 156 passed\n- npm run test:coverage: 1,166 passed, 23 skipped; statements 95.57 percent, branches 91.94 percent, functions 98.33 percent, lines 95.57 percent\n- npm run test:core: 402 passed, 23 skipped\n- npm run lint\n- npm run typecheck\n- npm run build\n- npm run smoke:cli\n- npm run check:pack: 43 files verified\n- npm run test:package: 18 passed\n- git diff --check\n\nA plain aggregate npm test invocation encountered existing intermittent readiness and operation-fixture failures outside the OAuth diff. Each exact failure passed five focused repetitions, the exact final coverage suite passed the full active test set, and evidence is recorded under canonical issue #122 without weakening tests or changing timeouts.

Summary by CodeRabbit

  • New Features

    • Added configuration format version 3 with strict, non-secret OAuth connection declarations.
    • Added secure connection metadata, credential lifecycle, validation, redacted auditing, and standardized OAuth error reporting.
    • Exposed OAuth configuration types through the public API.
  • Bug Fixes

    • Invalid, ambiguous, secret-bearing, or conflicting OAuth settings are rejected.
    • OAuth-enabled runtime configurations fail closed until authorization is available.
  • Documentation

    • Updated configuration, security, architecture, OAuth support, and migration guidance.
  • Refactor

    • Existing configurations now migrate to version 3.

@mohanagy

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Version 3 introduces strict, non-secret OAuth connection declarations, canonical binding and credential storage primitives, persistent lifecycle coordination, redacted auditing, migration support, and fail-closed runtime rejection until native authorization is enabled.

Changes

OAuth Version 3 configuration

Layer / File(s) Summary
Versioned configuration contract and validation
src/config/*, src/index.ts, tests/config-*, tests/public-api.test.ts, docs/*, examples/*
Configuration version 3 adds strict oauth.connections bindings, schema validation, public types, migration from versions 1 and 2, updated examples, and fail-closed OAuth documentation.
Binding identity and secure storage
src/oauth/connection-types.ts, src/oauth/canonical-resource.ts, src/oauth/local-lock.ts, src/oauth/secure-credential-store.ts, package.json, tests/oauth-connection-types.test.ts, tests/oauth-canonical-resource.test.ts, tests/oauth-secure-credential-store.test.ts
OAuth bindings are canonicalized, deterministically keyed, locally coordinated, persisted through the native keyring, and validated with secret redaction and no fallback storage.
Registry and lifecycle coordination
src/oauth/connection-registry.ts, src/oauth/connection-lifecycle.ts, tests/oauth-connection-registry.test.ts, tests/oauth-connection-lifecycle.test.ts
Connection metadata, credential states, refresh single-flight behavior, cancellation, timeout handling, compensation, disconnect protection, and cross-instance serialization are implemented and tested.
Audit and runtime boundary
src/audit/*, src/oauth/audit.ts, src/runtime/resolve-runtime-config.ts, src/utils/errors.ts, src/cli/exit-codes.ts, src/upstream/*, tests/oauth-audit.test.ts, tests/oauth-config.test.ts, tests/cli-exit-codes.test.ts
OAuth lifecycle state is recorded as redacted audit metadata, OAuth errors receive CLI mappings, shared case-insensitive header utilities support validation, and configured OAuth authorization fails with OAUTH_AUTHORIZATION_NOT_ENABLED.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

  • mohanagy/miftah#73 — Provides the earlier configuration migration framework extended here from v1→v2 to v1/v2→v3.
  • mohanagy/miftah#53 — Shares the audit event and lifecycle-writing infrastructure extended with OAuth state fields.
  • mohanagy/miftah#58 — Provides the CLI exit-code contract extended with OAuth error mappings.

Sequence Diagram(s)

sequenceDiagram
  participant Config
  participant Runtime
  participant OAuthConnectionLifecycle
  participant OAuthConnectionRegistry
  participant OAuthCredentialStore
  Config->>Runtime: resolve version 3 OAuth configuration
  Runtime-->>Config: reject with OAUTH_AUTHORIZATION_NOT_ENABLED
  OAuthConnectionLifecycle->>OAuthConnectionRegistry: manage connection metadata
  OAuthConnectionLifecycle->>OAuthCredentialStore: load or persist credentials
  OAuthConnectionLifecycle-->>OAuthConnectionRegistry: commit lifecycle state
Loading

Poem

A rabbit checks the bindings tight,
No secret tokens see the light.
The vault keeps keys in guarded stone,
While refresh hops are safely sewn.
“Not enabled yet,” the runtime sings—
V3 has built the safer springs.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Docstring Coverage ❌ Error Docstring coverage is 24.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a secure OAuth connection core.
Description check ✅ Passed The description covers the change, security boundary, and validation, though it uses custom headings instead of the template's exact sections.
Linked Issues check ✅ Passed The changes match #81: version-3 opaque OAuth records, secure-store lifecycle, redacted audits, migration support, and focused tests are all present.
Out of Scope Changes check ✅ Passed The diff stays focused on OAuth config, storage, lifecycle, docs, tests, and dependency wiring, with no clearly unrelated feature work.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/81-oauth-connection-core

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/config/migrate-config.ts`:
- Around line 132-138: Remove the redundant conditional guard and its duplicate
error path in the config migration flow, leaving a single unsupported-version
throw after the existing version handling for "3", "1", and "2". Preserve the
current MiftahError code and message behavior.

In `@src/config/schema.ts`:
- Around line 1204-1212: Update the addConfigIssue call in the hasMergedHeader
authorization conflict branch to report the diagnostic against the connection or
its upstream/headers location instead of [...path, "resource"]. Keep the
existing error code and messages unchanged.

In `@src/oauth/local-lock.ts`:
- Around line 120-137: Update the lock-acquisition flow around
inspectLocalLockPort and tryAcquireLocalLock so a given key cannot split across
candidate ports: reserve one deterministic port for each key, or scan all ports
for an existing same-key holder before acquiring any available port. Preserve
the existing timeout and OAuthLocalLockUnavailableError behavior while ensuring
contenders for the same key serialize across processes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: dcc12ba8-bbfd-40e3-879d-91467223a11c

📥 Commits

Reviewing files that changed from the base of the PR and between f8cd4ed and 3f6c78b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (50)
  • CHANGELOG.md
  • docs/architecture.md
  • docs/config.md
  • docs/library-api.md
  • docs/oauth-console-threat-model.md
  • docs/oauth-support.md
  • docs/security.md
  • examples/generic.miftah.json
  • examples/github.miftah.json
  • examples/multi-upstream.miftah.json
  • examples/plugins.miftah.json
  • examples/sentry.miftah.json
  • package.json
  • src/audit/audit-trail.ts
  • src/audit/audit-types.ts
  • src/cli/exit-codes.ts
  • src/config/generate-json-schema.ts
  • src/config/migrate-config.ts
  • src/config/presets.ts
  • src/config/schema.ts
  • src/config/types.ts
  • src/config/validate-config.ts
  • src/config/versions.ts
  • src/index.ts
  • src/oauth/audit.ts
  • src/oauth/canonical-resource.ts
  • src/oauth/connection-lifecycle.ts
  • src/oauth/connection-registry.ts
  • src/oauth/connection-types.ts
  • src/oauth/local-lock.ts
  • src/oauth/secure-credential-store.ts
  • src/runtime/resolve-runtime-config.ts
  • src/upstream/headers.ts
  • src/upstream/upstream-process-manager.ts
  • src/utils/errors.ts
  • tests/cli-exit-codes.test.ts
  • tests/config-diagnostics.test.ts
  • tests/config-migration.test.ts
  • tests/config-schema-contract.test.ts
  • tests/oauth-audit.test.ts
  • tests/oauth-canonical-resource.test.ts
  • tests/oauth-config.test.ts
  • tests/oauth-connection-lifecycle.test.ts
  • tests/oauth-connection-registry.test.ts
  • tests/oauth-connection-types.test.ts
  • tests/oauth-console-threat-model-docs-contract.test.ts
  • tests/oauth-secure-credential-store.test.ts
  • tests/oauth-support-docs-contract.test.ts
  • tests/package-contract.test.ts
  • tests/public-api.test.ts

Comment thread src/config/migrate-config.ts Outdated
Comment thread src/config/schema.ts
Comment thread src/oauth/local-lock.ts
@mohanagy
mohanagy dismissed coderabbitai[bot]’s stale review July 22, 2026 09:09

All three findings were addressed in commit 4e2dd28, replied to with focused validation evidence, and the review threads are resolved. CodeRabbit completed its incremental current-head review successfully with no new findings.

@mohanagy

Copy link
Copy Markdown
Owner Author

Final review exception record for exact head 4e2dd28:\n\n- CodeRabbit completed a substantive review of the preceding head and raised three findings. All three were fixed in 4e2dd28, replied to, and their threads are resolved.\n- CodeRabbit incremental comments on 4e2dd28 contained no new findings, but its final status is explicitly Review rate limited.\n- Per maintainer policy, a local Claude Opus review was attempted twice: first for the full development-to-head diff for more than five minutes, then for only commit 4e2dd28 for more than two minutes. Both processes remained active but produced no output and were terminated at bounded limits. They are not counted as reviews.\n- The incremental commit was manually reviewed for lock acquisition races, fail-closed timeout and cleanup behavior, diagnostic compatibility, and regression-test validity.\n- Exact-head CI run 29906763664 is green: Linux quality, Ubuntu, macOS, Windows Node 20, 22 and 24, and Verify all passed. Local exact-head npm test and coverage each passed 1,167 active tests with 23 platform skips; all release checks passed.\n\nGitHub reports the PR clean and mergeable, with no unresolved review threads.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Core] Add profile-bound OAuth connection records and secure credential lifecycle

1 participant