Skip to content

.#2031

Closed
liangshuo-1 wants to merge 1 commit into
mainfrom
feat/workspace-sdk-risk-protection
Closed

.#2031
liangshuo-1 wants to merge 1 commit into
mainfrom
feat/workspace-sdk-risk-protection

Conversation

@liangshuo-1

@liangshuo-1 liangshuo-1 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds configurable workspace risk-control policy, cached credential/config provenance, host OS and product-model signal collection, and SDK transport enforcement for restricted headers on eligible official HTTPS OpenAPI requests.

Changes

Risk-control signal flow

Layer / File(s) Summary
Workspace policy, snapshot, and CLI
internal/core/..., cmd/config/..., README*
Adds persisted riskControl policy with enabled-by-default resolution, invocation-scoped config snapshots, config risk-control on|off|default, command tests, and security documentation.
Credential provenance and shared configuration
internal/credential/...
Caches credential-source provenance and shares one workspace configuration snapshot across credential resolution and SDK setup.
Host signals and outbound transport
internal/riskcontrol/...
Adds OS/product-model discovery and validation plus a transport that strips restricted headers and injects trusted signals only for authorized requests to official HTTPS OpenAPI origins.
Factory SDK wiring and boundary validation
internal/cmdutil/...
Connects workspace policy and credential provenance to the SDK transport, preserves generic HTTP behavior, and tests workspace, external-credential, extension, and sidecar boundaries.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Factory
  participant CredentialProvider
  participant RiskControlTransport
  participant LarkAPI
  CLI->>Factory: Create invocation configuration
  Factory->>CredentialProvider: Resolve account and provenance
  CredentialProvider-->>Factory: Workspace-managed status
  Factory->>RiskControlTransport: Configure SDK transport policy
  RiskControlTransport->>LarkAPI: Eligible request with trusted signals
Loading

Possibly related PRs

  • larksuite/cli#532: Covers the sidecar credential and transport boundary tested for risk-control header non-leakage.
  • larksuite/cli#1213: Refactors the shared HTTP transport construction touched by this SDK wiring.
  • larksuite/cli#1910: Addresses related X-Agent-* security-header transport behavior.

Suggested labels: feature

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning No description was provided, so the required Summary, Changes, Test Plan, and Related Issues sections are missing. Add the template sections with a short summary, main changes, test plan, and related issues.
Title check ❓ Inconclusive The title is just a period and does not describe the pull request at all. Replace it with a concise, specific title that summarizes the main change.
✅ Passed checks (2 passed)
Check name Status Explanation
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.
✨ 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/workspace-sdk-risk-protection

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.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.13%. Comparing base (4807283) to head (1353303).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2031   +/-   ##
=======================================
  Coverage   75.13%   75.13%           
=======================================
  Files         905      905           
  Lines       96135    96135           
=======================================
  Hits        72229    72229           
  Misses      18348    18348           
  Partials     5558     5558           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@liangshuo-1
liangshuo-1 marked this pull request as ready for review July 24, 2026 04:08
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@1353303d4806ae1cf8f9a6fe6f13abae42890668

🧩 Skill update

npx skills add larksuite/cli#feat/workspace-sdk-risk-protection -y -g

@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 `@cmd/config/risk_control.go`:
- Around line 36-40: Update the RunE configuration-loading error path around
core.LoadOrNotConfigured to preserve already typed errors while wrapping raw
failures in the established typed internal/storage error and attaching the
original error with WithCause(err); continue returning successful configuration
results unchanged.

In `@internal/core/config.go`:
- Around line 69-73: Add adjacent unit coverage for
MultiAppConfig.RiskControlEnabled, directly asserting true when RiskControl is
omitted, true when explicitly enabled, and false when explicitly disabled. Keep
the existing explicit-false round-trip test, but ensure the resolver itself is
exercised for all three states.

In `@internal/credential/credential_provider.go`:
- Around line 263-275: Update the token-resolution flow around ResolveAccount so
every read of p.resolution.tokenSource, including the existing fast path, occurs
after participating in accountOnce or under the same synchronization protecting
resolution writes. Preserve the defaultAcct nil behavior and return the resolved
token source or existing error when initialization completes.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0211d66-767a-4021-8556-dc81e41b2a81

📥 Commits

Reviewing files that changed from the base of the PR and between b8f56db and 1e16cba.

📒 Files selected for processing (32)
  • README.md
  • README.zh.md
  • cmd/config/config.go
  • cmd/config/risk_control.go
  • cmd/config/risk_control_test.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/factory_proxy_warn_test.go
  • internal/cmdutil/factory_risk_control_test.go
  • internal/cmdutil/risk_control.go
  • internal/cmdutil/risk_control_route_sidecar_test.go
  • internal/cmdutil/risk_control_test.go
  • internal/cmdutil/secheader_test.go
  • internal/cmdutil/transport_test.go
  • internal/core/config.go
  • internal/core/config_snapshot.go
  • internal/core/config_snapshot_test.go
  • internal/core/config_test.go
  • internal/credential/credential_provider.go
  • internal/credential/credential_provider_test.go
  • internal/credential/default_provider.go
  • internal/credential/integration_test.go
  • internal/riskcontrol/host.go
  • internal/riskcontrol/host_darwin.go
  • internal/riskcontrol/host_darwin_test.go
  • internal/riskcontrol/host_linux.go
  • internal/riskcontrol/host_linux_test.go
  • internal/riskcontrol/host_other.go
  • internal/riskcontrol/host_test.go
  • internal/riskcontrol/host_windows.go
  • internal/riskcontrol/host_windows_test.go
  • internal/riskcontrol/transport.go
  • internal/riskcontrol/transport_test.go

Comment thread cmd/config/risk_control.go Outdated
Comment on lines +36 to +40
RunE: func(cmd *cobra.Command, args []string) error {
config, err := core.LoadOrNotConfigured()
if err != nil {
return err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Return a typed error for configuration-load failures.

Returning err directly can bypass the command error-envelope contract. Pass through already typed errors; wrap raw load failures with a typed internal/storage error and .WithCause(err).

Proposed fix
 			config, err := core.LoadOrNotConfigured()
 			if err != nil {
-				return err
+				if _, ok := errs.ProblemOf(err); ok {
+					return err
+				}
+				return errs.NewInternalError(errs.SubtypeStorage,
+					"failed to load risk-control policy: %v", err).WithCause(err)
 			}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RunE: func(cmd *cobra.Command, args []string) error {
config, err := core.LoadOrNotConfigured()
if err != nil {
return err
}
RunE: func(cmd *cobra.Command, args []string) error {
config, err := core.LoadOrNotConfigured()
if err != nil {
if _, ok := errs.ProblemOf(err); ok {
return err
}
return errs.NewInternalError(errs.SubtypeStorage,
"failed to load risk-control policy: %v", err).WithCause(err)
}
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 39-39: cmd/config/risk_control.go#L39
Added line #L39 was not covered by tests

🤖 Prompt for 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.

In `@cmd/config/risk_control.go` around lines 36 - 40, Update the RunE
configuration-loading error path around core.LoadOrNotConfigured to preserve
already typed errors while wrapping raw failures in the established typed
internal/storage error and attaching the original error with WithCause(err);
continue returning successful configuration results unchanged.

Sources: Coding guidelines, Learnings

Comment thread internal/core/config.go Outdated
Comment on lines +69 to +73
// RiskControlEnabled resolves the workspace policy. An omitted preference
// keeps the default-on account-protection behavior.
func (m *MultiAppConfig) RiskControlEnabled() bool {
return m != nil && (m.RiskControl == nil || *m.RiskControl)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Test the default-on resolver directly.

The round-trip test only verifies explicit false; it never calls RiskControlEnabled(). Cover omitted, explicit true, and explicit false so the default-on protection contract cannot regress unnoticed. Based on coding guidelines, “Every behavior change must include an adjacent test.”

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 71-72: internal/core/config.go#L71-L72
Added lines #L71 - L72 were not covered by tests

🤖 Prompt for 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.

In `@internal/core/config.go` around lines 69 - 73, Add adjacent unit coverage for
MultiAppConfig.RiskControlEnabled, directly asserting true when RiskControl is
omitted, true when explicitly enabled, and false when explicitly disabled. Keep
the existing explicit-false round-trip test, but ensure the resolver itself is
exercised for all three states.

Sources: Coding guidelines, Linters/SAST tools

Comment on lines +263 to +275
if p.resolution.tokenSource != nil {
return p.resolution.tokenSource, nil
}
if p.defaultAcct == nil {
return nil, nil
}
if _, err := p.ResolveAccount(ctx); err != nil {
return nil, err
}
if p.selectedSource == nil {
if p.resolution.tokenSource == nil {
return nil, fmt.Errorf("credential provider resolved an account without selecting a token source")
}
return p.selectedSource, nil
return p.resolution.tokenSource, nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Synchronize the resolution fast path.

This reads p.resolution.tokenSource before participating in accountOnce, while ResolveAccount writes the full resolution inside that sync.Once. Concurrent account and token resolution can therefore race, potentially observing a partially initialized token source. Resolve through ResolveAccount before reading the cached resolution, or guard all resolution reads/writes with a mutex.

🤖 Prompt for 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.

In `@internal/credential/credential_provider.go` around lines 263 - 275, Update
the token-resolution flow around ResolveAccount so every read of
p.resolution.tokenSource, including the existing fast path, occurs after
participating in accountOnce or under the same synchronization protecting
resolution writes. Preserve the defaultAcct nil behavior and return the resolved
token source or existing error when initialization completes.

@liangshuo-1
liangshuo-1 force-pushed the feat/workspace-sdk-risk-protection branch from 1e16cba to 3fce3ec Compare July 24, 2026 08:59
@github-actions github-actions Bot added domain/base PR touches the base domain domain/ccm PR touches the ccm domain domain/task PR touches the task domain size/XL Architecture-level or global-impact change and removed size/L Large or sensitive change across domains or core paths labels Jul 24, 2026
@liangshuo-1
liangshuo-1 force-pushed the feat/workspace-sdk-risk-protection branch from 3fce3ec to d644b3e Compare July 24, 2026 08:59
@github-actions github-actions Bot added size/L Large or sensitive change across domains or core paths and removed domain/base PR touches the base domain domain/ccm PR touches the ccm domain domain/task PR touches the task domain size/XL Architecture-level or global-impact change labels Jul 24, 2026
@liangshuo-1
liangshuo-1 force-pushed the feat/workspace-sdk-risk-protection branch from d644b3e to 1353303 Compare July 24, 2026 09:03
@github-actions github-actions Bot added size/M Single-domain feat or fix with limited business impact and removed size/L Large or sensitive change across domains or core paths labels Jul 24, 2026
@liangshuo-1 liangshuo-1 changed the title feat: add workspace-controlled SDK risk protection . Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant