Skip to content

feat(sidecar): auto-discover app scopes via API, remove offline_access fallback#1367

Open
hGrany wants to merge 1 commit into
larksuite:mainfrom
hGrany:feat/sidecar-scope-auto-discovery
Open

feat(sidecar): auto-discover app scopes via API, remove offline_access fallback#1367
hGrany wants to merge 1 commit into
larksuite:mainfrom
hGrany:feat/sidecar-scope-auto-discovery

Conversation

@hGrany

@hGrany hGrany commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

The multi-tenant sidecar demo previously fell back to offline_access when the scope cache was empty during handleLogin, resulting in scope_count=1 — effectively granting no useful permissions. This was a silent failure that was difficult to diagnose.

This PR replaces the fallback with scope auto-discovery:

  • API discovery: Query /open-apis/application/v6/applications/:app_id using the sidecar's tenant access token to discover all enabled user scopes.
  • TTL cache: Cache discovered scopes in discovered_scopes.json with a 24-hour TTL. Fresh cache is used directly; stale cache triggers a background refresh.
  • Graceful degradation: When the API fails but a stale cache exists, use stale scopes (degradation over interruption).
  • Explicit error: When both API discovery and cache are unavailable, return a 503 with a diagnostic message guiding the operator to enable the application:application:self_manage scope. No silent fallback to offline_access.
  • Backward-compatible: Still reads the legacy auth_login_scopes/ directory but always treats it as stale to trigger a fresh API discovery.

Prerequisite

The app must have the application:application:self_manage scope enabled so the sidecar can query its own scope list (read-only introspection).

Changes

File Change
auth_bridge.go Add resolveScopes(), discoverAppScopes(), loadScopeCache(), saveScopeCache(), scope cache types; modify handleLogin to use auto-discovery instead of offline_access fallback
handler_test.go Add 5 tests: API discovery, cache round-trip, TTL expiry, no-fallback behavior, stale-cache-on-API-failure
README.md Add "Scope auto-discovery" section; update design decisions

Test plan

  • TestDiscoverAppScopes_Success — mock API server returns scopes, verify parsing
  • TestScopeCacheRoundTrip — write/read cache, verify content
  • TestScopeCacheTTL — 25h-old cache is reported as stale
  • TestResolveScopesNoFallbackToOfflineAccess — no cache + no API = empty (not offline_access)
  • TestResolveScopesUsesStaleOnAPIFailure — stale cache used when API fails
  • All existing tests pass (no regression)

Made with Cursor

Summary by CodeRabbit

  • New Features
    • Added automatic OAuth scope discovery with intelligent caching (24-hour TTL) to simplify app configuration.
    • Improved error messages with actionable guidance when scope discovery encounters issues.
    • Implemented fallback to cached scopes during API failures for enhanced resilience.

…s fallback

The multi-tenant sidecar demo previously fell back to `offline_access` when
the scope cache was empty, resulting in scope_count=1 — effectively granting
no useful permissions.

Replace this silent failure with scope auto-discovery:

- Query /open-apis/application/v6/applications/:app_id using the sidecar's
  tenant access token to discover enabled user scopes.
- Cache discovered scopes in discovered_scopes.json with a 24-hour TTL.
- On API failure with existing stale cache, use stale scopes (degradation
  over interruption).
- On API failure with no cache, return an explicit 503 error with a
  diagnostic message — no fallback to offline_access.
- Backward-compatible: still reads legacy auth_login_scopes/ directory
  but always triggers a fresh API discovery.
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4c20a573-d198-4aba-bbd8-0a4b888fd3c8

📥 Commits

Reviewing files that changed from the base of the PR and between 7fdf558 and 278b6db.

📒 Files selected for processing (3)
  • sidecar/server-multi-tenant-demo/README.md
  • sidecar/server-multi-tenant-demo/auth_bridge.go
  • sidecar/server-multi-tenant-demo/handler_test.go

📝 Walkthrough

Walkthrough

Multi-tenant sidecar now auto-discovers OAuth scopes dynamically via Lark API with 24-hour TTL caching. When handleLogin lacks an explicit scope, it attempts fresh discovery, falls back to stale cache on API failure, and returns 503 with guidance when both are unavailable. Legacy auth_login_scopes/ directory is still supported but treated as stale to trigger refresh.

Changes

Scope auto-discovery and caching

Layer / File(s) Summary
Scope auto-discovery documentation
sidecar/server-multi-tenant-demo/README.md
Scope auto-discovery section documents cache-first behavior (24h freshness), Lark API discovery fallback, stale-cache fallback on API failure, and 503 error path when neither is available; design decisions clarify no-offline-access policy and prerequisite application:application:self_manage permission; source layout updated.
Scope discovery and cache infrastructure
sidecar/server-multi-tenant-demo/auth_bridge.go
New scope caching system with scopeCacheRecord (TTL-based staleness checks), resolveScopes() (priority: fresh cache → API discovery → stale cache), loadScopeCache() (backward-compatible with legacy directory), discoverAppScopes() (fetches user scopes from Lark API), and saveScopeCache() (atomic persistence).
Login endpoint scope integration
sidecar/server-multi-tenant-demo/auth_bridge.go
handleLogin now calls resolveScopes(r.Context()) to derive OAuth scopes dynamically, with improved error messaging when discovery fails (includes guidance to enable required permissions and Feishu app link).
Scope discovery and caching tests
sidecar/server-multi-tenant-demo/handler_test.go
Five new tests validate API-driven scope discovery HTTP flow, cache persistence round-trip, TTL staleness detection at 25 hours, empty return when no cache exists, and cached fallback when API fails.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • larksuite/cli#934: Added initial multi-tenant auth bridge with legacy cached-scope handling; this PR replaces that mechanism with dynamic API-driven scope auto-discovery and TTL caching.

Suggested labels

size/L

Suggested reviewers

  • sang-neo03

Poem

🐰 Scopes discovered, cached with care,
Fresh data flows, no stale despair,
API calls when cache grows old,
Fallback tales the system told,
Login whispers, "Find my way!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% 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 clearly summarizes the main change: auto-discover app scopes via API and remove the offline_access fallback, which aligns with the changeset's primary objective.
Description check ✅ Passed The description covers all required template sections: a clear summary explaining the motivation, detailed changes with a file-change table, and a comprehensive test plan with checkmarks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant