Skip to content

Update Lockr integration to use dedicated trust-server SDK#395

Open
ChristianPavilonis wants to merge 1 commit intomainfrom
feature/lockr-sdk-update
Open

Update Lockr integration to use dedicated trust-server SDK#395
ChristianPavilonis wants to merge 1 commit intomainfrom
feature/lockr-sdk-update

Conversation

@ChristianPavilonis
Copy link
Collaborator

@ChristianPavilonis ChristianPavilonis commented Mar 3, 2026

Summary

  • Switch to Lockr's dedicated trust-server SDK (identity-lockr-trust-server.js) which is pre-configured to route API calls through the first-party proxy, eliminating our fragile runtime regex host rewriting
  • Remove rewrite_sdk_host config and regex logic — the new SDK handles this natively, so handle_sdk_serving() now serves the SDK as-is with no conditional rewriting
  • Add debug logging with [lockr] prefix for diagnosing production attribute rewriting issues

Changes

File Change
crates/common/src/integrations/lockr.rs Updated default sdk_url to identity-lockr-trust-server.js; removed rewrite_sdk_host config field, rewrite_sdk_host() regex method, default_rewrite_sdk_host() fn, and regex import; simplified handle_sdk_serving() to serve SDK without host rewriting or X-Lockr-Host-Rewritten header; fixed operator precedence in is_lockr_sdk_url() with explicit parentheses; added tracing::debug! logging to register() and rewrite(); removed 4 host-rewriting tests, extracted test_config()/test_context() helpers, added test_attribute_rewriter_keeps_non_lockr_urls and trust-server SDK URL detection test
trusted-server.toml Updated example sdk_url to match new default (identity-lockr-trust-server.js)

Closes

Closes #394
Closes #150

Test plan

  • cargo test --workspace
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • JS tests: cd crates/js/lib && npx vitest run
  • JS format: cd crates/js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: N/A

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses tracing macros (not println!)
  • New code has tests
  • No secrets or credentials committed

Backward compatibility

LockrConfig does not have #[serde(deny_unknown_fields)], so existing configs with rewrite_sdk_host will be silently ignored during deserialization. No breakage.

Lockr now provides a pre-configured SDK (identity-lockr-trust-server.js) that
routes API calls through the first-party proxy out of the box. This eliminates
the need for fragile runtime regex rewriting of obfuscated host assignments in
the SDK JavaScript.

- Update default sdk_url to identity-lockr-trust-server.js
- Remove rewrite_sdk_host config field, regex method, and related tests
- Simplify handle_sdk_serving to serve SDK as-is (no host rewriting)
- Fix operator precedence in is_lockr_sdk_url (clarity, no behavioral change)
- Add debug logging to attribute rewriter for diagnosing rewrite issues
- Extract test helpers, add trust-server URL detection test
@ChristianPavilonis ChristianPavilonis force-pushed the feature/lockr-sdk-update branch from 92cc71c to c2f1452 Compare March 3, 2026 15:34
Copy link
Collaborator

@prk-Jr prk-Jr left a comment

Choose a reason for hiding this comment

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

👍 Looks good to me.

@aram356 aram356 linked an issue Mar 5, 2026 that may be closed by this pull request
1 task
Copy link
Collaborator

@aram356 aram356 left a comment

Choose a reason for hiding this comment

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

Summary

Good simplification — replaces fragile regex-based SDK host rewriting with a dedicated trust-server SDK from Lockr. Removes the regex dependency from this module, cleans up tests, and reduces code by ~190 lines. Two issues need attention before merge: the aim.loc.kr URL matching is overly broad, and removing rewrite_sdk_host without a deprecation warning risks silent privacy regressions for existing deployments.

Blocking

🔧 wrench

  • Overly broad aim.loc.kr URL matching: any URL on that domain matches, including non-JS resources (lockr.rs:94)
  • Silent config drop for rewrite_sdk_host: existing deployments lose host rewriting without warning (lockr.rs:31)

Non-blocking

🤔 thinking

  • Contract coverage regressed: no test asserts the new SDK-served-as-is contract (lockr.rs:361)

🏕 camp site

  • Verbose debug logging: log::debug! fires for every attribute on every page (lockr.rs:322)

📝 note

  • Redundant guard is consistent: defensive rewrite_sdk check matches other integrations (lockr.rs:316)

📌 out of scope

  • API endpoint domain mismatch (pre-existing): code default identity.lockr.kr vs TOML identity.loc.kr — worth a follow-up

🌱 seedling

  • SDK mode header: consider X-Lockr-SDK-Mode for migration observability (lockr.rs:153)

👍 praise

  • Test helpers and assertions: test_config(), test_context(), descriptive messages (lockr.rs:365)

CI Status

  • fmt: PASS
  • clippy: PASS
  • rust tests: PASS
  • js tests: PASS

@@ -103,48 +92,22 @@ impl LockrIntegration {
fn is_lockr_sdk_url(&self, url: &str) -> bool {
let lower = url.to_ascii_lowercase();
lower.contains("aim.loc.kr")
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔧 wrenchaim.loc.kr branch matches any URL on that domain (images, CSS, etc.) without requiring identity-lockr or .js. The identity.loc.kr branch correctly applies both guards, but aim.loc.kr does not.

For example, <img src="https://aim.loc.kr/pixel.gif"> would be rewritten to the SDK proxy endpoint.

Fix: Apply the same specificity to both branches:

fn is_lockr_sdk_url(&self, url: &str) -> bool {
    let lower = url.to_ascii_lowercase();
    (lower.contains("aim.loc.kr") || lower.contains("identity.loc.kr"))
        && lower.contains("identity-lockr")
        && lower.ends_with(".js")
}

Also add negative test cases:

assert!(!integration.is_lockr_sdk_url("https://aim.loc.kr/pixel.gif"));
assert!(!integration.is_lockr_sdk_url("https://aim.loc.kr/styles.css"));

@@ -64,10 +57,6 @@ pub struct LockrConfig {
#[serde(default = "default_rewrite_sdk")]
pub rewrite_sdk: bool,
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔧 wrench — The removed rewrite_sdk_host field (previously just below this line) will be silently ignored by serde in existing configs. Deployments that still use identity-lockr-v1.0.js with rewrite_sdk_host = true will silently lose host rewriting — API calls from the SDK will bypass the first-party /integrations/lockr/api proxy and go directly to Lockr's servers.

Fix (either):

  • (a) Add a deprecated field that warns at startup:
/// Deprecated — the trust-server SDK handles host routing natively.
#[serde(default)]
rewrite_sdk_host: Option<bool>,

Then in register():

if integration.config.rewrite_sdk_host.is_some() {
    log::warn!("lockr: `rewrite_sdk_host` is deprecated and ignored; \
                the trust-server SDK handles host routing natively");
}
  • (b) At minimum, warn when sdk_url does not contain trust-server:
if !integration.config.sdk_url.contains("trust-server") {
    log::warn!("lockr: sdk_url does not appear to be a trust-server SDK; \
                API calls may bypass first-party routing");
}

true
}

#[cfg(test)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

🤔 thinking — The old host-rewriting tests were correctly removed, but no replacement test asserts the new contract: that the SDK is served unmodified and default_sdk_url() contains trust-server. A simple assertion would document this assumption and prevent a future default URL change from silently breaking first-party routing.

// Rewrite to first-party SDK endpoint
AttributeRewriteAction::Replace(format!(
let is_lockr = self.is_lockr_sdk_url(attr_value);
log::debug!(
Copy link
Collaborator

Choose a reason for hiding this comment

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

🏕 camp site — This log::debug! runs for every src/href attribute on every HTML page, even for non-Lockr URLs. Consider log::trace! or only logging when is_lockr is true. Other integrations (datadome, gpt, permutive) don't log at this granularity in rewrite().

@@ -364,22 +314,30 @@ impl IntegrationAttributeRewriter for LockrIntegration {
ctx: &IntegrationAttributeContext<'_>,
) -> AttributeRewriteAction {
if !self.config.rewrite_sdk {
Copy link
Collaborator

Choose a reason for hiding this comment

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

📝 note — This rewrite_sdk guard is redundant since handles_attribute() already checks it, but this defensive pattern is used consistently across other integrations (permutive, gpt, testlight). No action needed — just noting for awareness.

"X-Lockr-Host-Rewritten",
self.config.rewrite_sdk_host.to_string(),
)
.with_body(sdk_body))
Copy link
Collaborator

Choose a reason for hiding this comment

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

🌱 seedling — The X-Lockr-Host-Rewritten header removal is correct since the feature is gone. For migration observability, consider adding X-Lockr-SDK-Mode: trust-server so operators can confirm which SDK variant is being served.

#[test]
fn test_lockr_sdk_url_detection() {
let config = LockrConfig {
fn test_config() -> LockrConfig {
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 praise — Nice extraction of test_config() and test_context() helpers, descriptive "should ..." assertion messages, and the new test_attribute_rewriter_keeps_non_lockr_urls test. Follows project testing conventions well.

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

Labels

None yet

Projects

None yet

3 participants