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​