Overview
What it does
Section titled “What it does”Access Gate protects named page, download, or member-area routes. Visitors without a matching grant can request access; authorised reviewers can approve, reject, expire, resend, or revoke access and investigate the resulting audit history.
Before you protect content
Section titled “Before you protect content”An integrator must run the package install flow and attach the Access Gate middleware with the intended area key to every route that needs protection. Creating an area in the admin does not protect a route by itself. The install command creates its default area as Paused so content is not accidentally gated before this wiring is checked.
Run capell:access-gate-doctor after setup and test the protected URL as a signed-out visitor, an approved visitor, and a revoked visitor. Gated responses are private and excluded from public HTML caching; missing storage returns a private 503, and a protected route with no matching area fails closed.
Where it shows up
Section titled “Where it shows up”Go to Workflow > Access Gate. What each user can see or change depends on their Access Gate resource permissions and assigned-site scope.
- Access areas controls the area key, site, status, schedule, identity and approval modes, grant lifetime, token policy, public exceptions, claim destination, and optional announcement.
- Registrations lists requests and provides approve, reject, expire, bulk approve, and claim-link resend actions when the request state permits them.
- Grants shows who can currently enter and lets an authorised reviewer revoke the underlying access.
- Claim links and Browser sessions show link/device lifecycle state. A browser session can be revoked without revoking every session on the grant.
- Audit events records requests, decisions, claims, grants, revocations, and denied visits. Use
capell:access-gate-audit-exportwhen a filtered CSV is required.
Site Lockdown
Section titled “Site Lockdown”Site Lockdown protects an entire human-facing host before controllers, public rendering, HTML Cache, or static output. In System > Sites, open Access Protection to set the site default and optional domain overrides. A protected policy can accept a shared password, a signed-in account assigned to that site (global admins also qualify), a trusted upstream assertion, or any configured combination of those alternatives.
Environment protection is an explicit one-way ratchet. ACCESS_GATE_SITE_LOCKDOWN_FORCE_HOSTS can force selected hosts but the database cannot turn those hosts off or widen ACCESS_GATE_SITE_LOCKDOWN_FORCE_METHODS. Point ACCESS_GATE_SITE_LOCKDOWN_FORCE_PROFILE at a named profile and provide its secret outside Git. Do not infer protection from APP_ENV.
Set ACCESS_GATE_SITE_LOCKDOWN_DISCOVERY_THROUGH_LARAVEL=true only after the protected host routes robots, sitemap, feed, manifest, and llms requests through Laravel. The doctor check treats this as operator evidence and the deployment smoke verifies the live responses.
Shared-password access lasts for the browser session unless an absolute timeout is set. Changing a policy or credential increments its revision and invalidates existing sessions. ?pass=… performs a one-time exchange and immediately redirects to a URL without the parameter; upstream access logs can still observe that initial request, so prefer the form or HTTP Basic for routine automation.
Database passwords are Argon2id hashes by default. Recoverable encrypted storage must be explicitly enabled and secret reveal requires a password-confirmed, audited admin flow. Named configuration profiles are useful for deployment-managed credentials. If a protected database policy cannot be resolved, Access Gate returns a private 503; an environment-forced profile remains enforceable without package storage.
Site duplication and SiteSpec portability copy only policy shape, method choices, timeouts, revisions, and named profile references. Database password hashes and encrypted password values are never copied. Imported shared-password policies therefore remain protected but return a private 503 until an operator supplies a database credential or a valid named profile.
All protected responses, including authorised pages and /up, carry Cache-Control: private, no-store and X-Robots-Tag: noindex, nofollow, nosnippet. Protected robots.txt is replaced with Disallow: /; sitemaps, feeds, manifests and discovery documents remain behind authentication. Access/logout, required login callbacks, /up, the lockdown robots response and static assets are the only built-in exemptions. Add machine exemptions in code through SiteAccessExemptionContributor, never through database wildcards.
Run capell:access-gate-doctor after configuration. It reports forced hosts, effective methods, named profile availability, storage, middleware/cache ordering and route throttles without printing secrets. Policy changes clear HTML Cache and generated static artifacts. Do not generate or publish a static site while protection is active.
Server and proxy notes
Section titled “Server and proxy notes”- Route
/robots.txt,/sitemap.xml,/feed,/site.webmanifest,/llms.txtand similar discovery paths through Laravel on a protected host; do not let Nginx or Apache serve generated files ahead of the application. - At Cloudflare or another proxy, bypass caching for protected hosts and preserve the application’s private/no-store and robots headers.
- Trust an upstream assertion only from explicit proxy IP addresses and require an exact configured header value. Never trust a client-controlled header from the public internet.
- Recovery is configuration-first: restore the named credential profile or disable the explicit force-host setting during rollback. Keep
/uprouted to Laravel and public for deployment health checks.
Configure an access area safely
Section titled “Configure an access area safely”- Active gates only inside its optional open/close window. Before the opening time and after the closing time, the protected route is allowed through; omit the window when content must remain gated continuously.
- Paused does not gate the route but still accepts registrations. Closed does not gate the route and rejects new registrations.
- Guest link recognises the browser token created from an emailed claim link. Authenticated requires a valid user or verified-email grant. Hybrid accepts either.
- Approval can be manual, automatic, invite-only, or automatic for the first configured number of approvals. The approval limit controls only the first N auto-approve strategy; it is not a hard cap on later manual approvals.
- Single per email reuses an existing request and can resend access for an already approved or claimed email. Duplicate allowed creates separate requests.
- With Single active browser token, a new claimed browser token replaces the previous active token for that grant. Choose multiple tokens only when the same grant should work on several browsers.
- A site-scoped area applies only to that site. A global area can cover every site, so reserve it for global operators. Treat public allowlist entries as deliberate bypasses and keep them as narrow paths or exact URLs.
Access lifecycle and recovery
Section titled “Access lifecycle and recovery”Approving a pending request creates a grant and sends a one-time claim link when the identity mode uses guest access. Claim links expire after seven days by default. A browser token defaults to 180 days but cannot outlive its grant; the grant itself follows Grant duration days. Resending creates a fresh claim link only while an active grant still exists.
Revoking a grant also revokes its active claim links and browser tokens. If one device alone is lost or shared, revoke that Browser session instead. Check the claim-link state, grant expiry, area status/schedule, and audit events when an approved person remains blocked.
Data, privacy, and retention
Section titled “Data, privacy, and retention”Access Gate stores registration email and configured field values, requested URLs, grants, hashed claim/browser tokens, keyed IP fingerprints, browser use timestamps, and audit events. Privacy Center can export or erase records associated with a person when that package is installed.
capell:access-gate-prune removes stale claim/browser tokens and expired registrations after 90 days by default, and audit events after 365 days. The package does not register that command with Laravel’s scheduler; schedule it in the host application if those retention windows must be enforced automatically. Use --dry-run first to report what would be deleted.
For how to use Access Gate, see the admin guide. For developers: see the README.