Skip to main content

WAC

Control who can access what. Simple, effective access control for the decentralized web.

Overview

Web Access Control (WAC) is a decentralized cross-domain access control system. It allows users to control access to their resources using simple rules stored in .acl files.

Key Concepts

ACL Files

Every resource can have an associated ACL file:

┌─────────────────────────────────────────────────────────────────┐
│ WAC Structure │
├─────────────────────────────────────────────────────────────────┤
│ │
│ /alice/profile ← The resource │
│ /alice/profile.acl ← Its access control │
│ │
│ /alice/photos/ ← A container │
│ /alice/photos/.acl ← Container's access control │
│ │
│ ACL files control who can Read, Write, Append, Control │
│ │
└─────────────────────────────────────────────────────────────────┘

Permission Modes

ModeDescription
ReadView the resource content
WriteModify or delete the resource
AppendAdd to the resource (no modify/delete)
ControlModify the ACL itself

Agent Types

Agent TypeDescription
acl:agentSpecific WebID
acl:agentClassGroup of agents
acl:agentGroupvCard group
foaf:AgentAnyone (authenticated or not)
acl:AuthenticatedAgentAny authenticated user

ACL Syntax

Basic Example

@prefix acl: <http://www.w3.org/ns/auth/acl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

# Owner has full control
<#owner>
a acl:Authorization ;
acl:agent <https://alice.example/profile/card#me> ;
acl:accessTo <./profile> ;
acl:mode acl:Read, acl:Write, acl:Control .

# Public can read
<#public>
a acl:Authorization ;
acl:agentClass foaf:Agent ;
acl:accessTo <./profile> ;
acl:mode acl:Read .

Container with Default

@prefix acl: <http://www.w3.org/ns/auth/acl#> .

# Alice controls the photos container
<#owner>
a acl:Authorization ;
acl:agent <https://alice.example/profile/card#me> ;
acl:accessTo </photos/> ;
acl:default </photos/> ;
acl:mode acl:Read, acl:Write, acl:Control .

# Friends can read photos
<#friends>
a acl:Authorization ;
acl:agentClass </friends#group> ;
acl:accessTo </photos/> ;
acl:default </photos/> ;
acl:mode acl:Read .

Key Properties

PropertyPurpose
acl:accessToResource this rule applies to
acl:defaultApply to container children
acl:modePermissions granted
acl:agentSpecific agent(s)
acl:agentClassClass of agents
acl:originAllowed app origins

Access Patterns

Public Resource

<#public>
a acl:Authorization ;
acl:agentClass foaf:Agent ;
acl:accessTo <./document> ;
acl:mode acl:Read .

Private Resource

<#owner>
a acl:Authorization ;
acl:agent <https://alice.example/profile/card#me> ;
acl:accessTo <./diary> ;
acl:mode acl:Read, acl:Write, acl:Control .

Shared with Specific Person

<#shared>
a acl:Authorization ;
acl:agent <https://bob.example/profile/card#me> ;
acl:accessTo <./document> ;
acl:mode acl:Read .

Append-Only (Comments)

<#commenters>
a acl:Authorization ;
acl:agentClass acl:AuthenticatedAgent ;
acl:accessTo <./comments> ;
acl:mode acl:Append .

Inheritance

┌─────────────────────────────────────────────────────────────────┐
│ ACL Inheritance │
├─────────────────────────────────────────────────────────────────┤
│ │
│ /alice/ │
│ /alice/.acl ← Root ACL with defaults │
│ │
│ /alice/photos/ │
│ /alice/photos/.acl ← Overrides root for /photos/ │
│ │
│ /alice/photos/vacation.jpg │
│ (no .acl) ← Inherits from /alice/photos/.acl │
│ │
│ /alice/photos/private.jpg │
│ /alice/photos/private.jpg.acl ← Specific override │
│ │
└─────────────────────────────────────────────────────────────────┘

Origin Control

Restrict which apps can access:

<#app-limited>
a acl:Authorization ;
acl:agent <https://alice.example/profile/card#me> ;
acl:accessTo <./sensitive> ;
acl:mode acl:Read, acl:Write ;
acl:origin <https://trusted-app.example> .

Comparison with ACP

FeatureWACACP
ComplexitySimpleMore expressive
Learning curveLowerHigher
FlexibilityGoodExcellent
MaturityStableNewer
Default inNSS, JSSCSS

Implementation

Check Permission

// Server checks ACL before responding
async function checkAccess(resource, agent, mode) {
const aclUrl = await findAcl(resource);
const acl = await fetch(aclUrl);
return hasPermission(acl, agent, mode);
}

Finding the ACL

  1. Check for resource.acl
  2. If not found, check parent container's .acl with acl:default
  3. Continue up to root

See Also