Representative interview topic

System design interview: How would you design permissioned external storage with LWS?

System designHard
Offer.cc Editorial TeamPublished Updated

Question

Design an interoperable external data-storage service for multiple applications. Clients must discover storage, request read/write access, create resources, and subscribe to changes. Explain resource modeling, HTTP semantics, authentication, concurrency, notifications, and rollback.

Prompt and scope

Design an interoperable external data-storage service for multiple applications. Clients must discover storage, request read/write access, create resources, and subscribe to changes. Explain resource modeling, HTTP semantics, authentication, concurrency, notifications, and rollback.

The W3C Linked Web Storage Protocol 1.0 is currently a Working Draft. It aims to give applications secure, permissioned, interoperable access to externally stored data. The specification uses Link relations to discover storage and parent resources, manages metadata through linksets, and requires atomicity between metadata updates and resource operations. The question tests protocol boundaries and failure handling without treating the draft as a stable standard.

What the interviewer evaluates

The interviewer looks for separations between resources, permissions, identity, metadata, and notifications, plus correct handling of POST retries, concurrent PATCH, 405/415 responses, caching, and revocation. A strong answer acknowledges Working Draft uncertainty and chooses among OpenID Connect, SAML, and self-signed identity suites based on deployment needs.

Clarifying questions before answering

  • Who operates the data owner, application, and storage service, and where are the trust boundaries?
  • Which operations are required: read, create, update, delete, sharing, or read-only subscriptions?
  • Are permissions granted by user, agent, resource path, action, or time window?
  • Are cross-region access, offline use, audit, revocation, and eventual notification required?
  • Can clients handle Link discovery, ETags, 405/415 responses, and retry deduplication?

30-second answer framework

“I would model storage, containers, data resources, linksets, identity, and grants separately. A client discovers storage and its parent through Link relations, authenticates with a declared suite, and submits a request containing action, subject, target, and constraints. Creation uses POST, but an idempotency key or deduplication prevents retry duplicates; metadata PATCH requires a concurrency condition and commits atomically with the resource operation. The service uses ETags, capability headers, and structured errors for conflicts, while a retryable queue delivers eventually consistent notifications. Each canary keeps revocation, old permission versions, and audit rollback.”

Step-by-step deep answer

1. Establish the resource and discovery model

Separate storage, container, data resource, and linkset. GET or HEAD responses expose the storage root, parent, type, and linkset through Link relations; clients must not treat URL layout as the protocol contract. A storage description should advertise server capabilities and media types so clients negotiate before sending PUT or a specific PATCH.

2. Model permissions as auditable grants

A grant should include assignee, action, target, constraints, issuer, validity, and revocation state. The storage service checks caller identity and grant version, then enforces least-privilege read, create, update, or delete. OpenID Connect, SAML, or self-signed identity can prove identity, but authentication and resource authorization remain separate; successful login does not imply access to every resource.

3. Define creation, update, and concurrency semantics

The specification creates a resource with POST and a server-assigned final URI, returning 201 and Location. POST is not idempotent, so retries need a unique request identifier or deduplication record. Linkset PATCH is the primary metadata update; use ETag, If-Match, or an equivalent version check to prevent lost updates. Return 405 for an unsupported method and 415 for an unsupported media type.

text
POST /alice/notes/ HTTP/2
Idempotency-Key: 7b3c...
Link: <https://www.w3.org/ns/lws#DataResource>; rel="type"
Content-Type: text/plain

meeting notes

4. Keep resource and metadata consistent

Creation, container membership, and required server metadata must commit atomically; failure must not leave a visible resource without a parent relation or linkset. Across shards, use a transaction log or outbox to record state. Read APIs can expose pending, committed, or failed states rather than inferring commit success from notification order.

5. Design notifications and capability negotiation

Write change events to a retryable outbox, then deliver them to subscriber inboxes. Include storage, resource, action, and version; consumers deduplicate by event ID and use GET to verify current state. Recover lost notifications with replay or periodic reconciliation, and keep duplicate processing idempotent. Prefer, Link, and media-type negotiation let clients adopt capabilities incrementally instead of assuming every server supports one PATCH or subscription model.

6. Handle authentication, revocation, and rollback

Include key rotation, token audience, clock skew, and revocation paths in the authentication design. Write permission changes to versioned audit logs and make revocation effective after authorization checks and cache invalidation. Canary low-risk tenants first, observing 401/403, 405/415, conflict rate, duplicate creation, notification latency, and audit completeness; stop on privilege escalation or orphaned data and restore the old authorization policy.

High-quality sample answer

I would separate storage, containers, data resources, linksets, identity, and grants. Clients discover the storage root, parent, type, and linkset through GET/HEAD Link relations, then negotiate capabilities before writes. A grant contains subject, action, target, constraints, validity, and revocation; OpenID Connect, SAML, or self-signed identity proves identity but does not grant resource access. POST returns 201 and Location; because it is not idempotent, clients use a unique request ID or deduplication. Linkset PATCH uses ETag/If-Match to prevent lost concurrent updates, and unsupported methods or media types return 405/415. Creation, membership, and server metadata commit atomically. Outbox events go to retryable inboxes, and consumers deduplicate by event ID and reconcile with GET. Canary rollout observes 401/403, conflicts, duplicates, notification latency, and audit completeness; privilege escalation, orphaned resources, or failed rollback stops the rollout. Since the protocol is a Working Draft, the final protocol and test matrix must be versioned.

Common mistakes

  • Treating URL paths as the whole protocol contract → discovery and capability negotiation break → depend on Link relations, media types, and capability headers.
  • Retrying POST unconditionally → duplicate resources may be created → use idempotency keys, deduplication records, and final-state reads.
  • Checking login but not authorization → identity does not imply access to the target → evaluate subject, action, target, and constraints.
  • Committing metadata separately from the resource → orphaned resources or incorrect linksets appear → use an atomic transaction or recoverable outbox.
  • Assuming every server supports PUT/PATCH → clients become brittle → discover capabilities and handle 405/415.

Follow-up questions and responses

Why cannot POST retries rely on TCP or HTTP alone?

The connection may fail after the server commits, leaving the client unaware of the result. A unique request ID and status query associate a retry with the original commit.

How do you avoid revocation lag from permission caches?

Use versioned grants with short TTLs, actively invalidate affected caches after the audit write, and recheck the authorization version for critical writes.

How do you recover from lost notifications?

Persist events in an outbox, retry delivery, retain consumer cursors, reconcile by resource version, and replay the event log when necessary.

Why must linkset updates be atomic?

If the resource succeeds but membership or type metadata does not, discovery, authorization, and caches observe inconsistent state. Atomic commit prevents a half-created resource from becoming visible.

How do you control investment during a Working Draft?

Use an isolated adapter and versioned test matrix, trial low-risk traffic only, keep the old protocol and migration path, and expand after the specification and implementation report stabilize.

Public sources

Related questions

Related interview tool

Use Solve for a system design answer

Clarify the requirements first, then move through scale, architecture, component choices, and trade-offs.

View the tool