{"id":349213,"date":"2026-08-12T21:12:18","date_gmt":"2026-08-12T21:12:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/folio-drawbridge\/"},"modified":"2026-08-12T21:12:10","modified_gmt":"2026-08-12T21:12:10","slug":"folio-drawbridge","status":"publish","type":"plugin","link":"https:\/\/dzo.wordpress.org\/plugins\/folio-drawbridge\/","author":13599663,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2.0","stable_tag":"1.2.0","tested":"7.0.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Folio Drawbridge","header_author":"buffcleb","header_description":"Encrypted file vaults with two-factor external sharing, comprehensive audit logging, lifecycle management, and role-based vault oversight.","assets_banners_color":"243534","last_updated":"2026-08-12 21:12:10","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/buffcleb\/folio-drawbridge","header_author_uri":"https:\/\/github.com\/buffcleb","rating":0,"author_block_rating":0,"active_installs":0,"downloads":39,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.0":{"tag":"1.2.0","author":"buffcleb","date":"2026-08-12 21:12:10"}},"upgrade_notice":{"1.2.0":"<p>Adds multi-file upload, ZIP download, notification emails, file type restrictions, storage quotas, and OTP rate limiting. Schema updates run automatically.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3644001,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3644001,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3644001,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3644001,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3644001,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3644001,"resolution":"1","location":"assets","locale":"","width":8012,"height":4866},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3644001,"resolution":"2","location":"assets","locale":"","width":2596,"height":2632},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3644001,"resolution":"3","location":"assets","locale":"","width":1192,"height":1158},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3644001,"resolution":"4","location":"assets","locale":"","width":2596,"height":1636},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3644001,"resolution":"5","location":"assets","locale":"","width":2604,"height":1536},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3644001,"resolution":"6","location":"assets","locale":"","width":2584,"height":1586},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3644001,"resolution":"7","location":"assets","locale":"","width":2576,"height":668},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3644001,"resolution":"8","location":"assets","locale":"","width":2612,"height":2470},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3644001,"resolution":"9","location":"assets","locale":"","width":2574,"height":882}},"screenshots":{"1":"Admin dashboard \u2014 vault, file, share, and download totals, seven-day download activity, recent events, and the security status panel showing key source, algorithm, storage protection, and cron health.","2":"Vault inspector \u2014 encrypted file list with per-file admin download, shares showing live status including \"Limit reached\", ownership transfer, status control, and the vault's own audit trail.","3":"Recipient download page after two-factor verification, with per-file downloads and the ZIP bulk download option.","4":"Settings \u2014 two-factor verification (code validity, attempt limit, request rate limit) and download limits.","5":"Settings \u2014 link expiration defaults and ceilings, chunked upload size limit, and audit log retention.","6":"Settings \u2014 encryption key source and generator, SIEM log file export, and owner notification options.","7":"Settings \u2014 file type allowlist and per-user storage quotas.","8":"Settings \u2014 customisable templates for all four system emails, each with its available placeholder tokens.","9":"Settings \u2014 data removal policy on uninstall, the storage folder name inside the uploads directory, and the resolved encrypted storage location with its protection status."}},"plugin_section":[262246],"plugin_tags":[8534,12167,12683,58819,9217],"plugin_category":[],"plugin_contributors":[267964],"plugin_business_model":[],"class_list":["post-349213","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-audit-log","plugin_tags-encryption","plugin_tags-file-sharing","plugin_tags-secure-files","plugin_tags-two-factor","plugin_contributors-buffcleb","plugin_committers-buffcleb"],"banners":{"banner":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/banner-772x250.png?rev=3644001","banner_2x":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/banner-1544x500.png?rev=3644001","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/icon.svg?rev=3644001","icon":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/icon.svg?rev=3644001","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-1.png?rev=3644001","caption":"Admin dashboard \u2014 vault, file, share, and download totals, seven-day download activity, recent events, and the security status panel showing key source, algorithm, storage protection, and cron health."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-2.png?rev=3644001","caption":"Vault inspector \u2014 encrypted file list with per-file admin download, shares showing live status including \"Limit reached\", ownership transfer, status control, and the vault's own audit trail."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-3.png?rev=3644001","caption":"Recipient download page after two-factor verification, with per-file downloads and the ZIP bulk download option."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-4.png?rev=3644001","caption":"Settings \u2014 two-factor verification (code validity, attempt limit, request rate limit) and download limits."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-5.png?rev=3644001","caption":"Settings \u2014 link expiration defaults and ceilings, chunked upload size limit, and audit log retention."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-6.png?rev=3644001","caption":"Settings \u2014 encryption key source and generator, SIEM log file export, and owner notification options."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-7.png?rev=3644001","caption":"Settings \u2014 file type allowlist and per-user storage quotas."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-8.png?rev=3644001","caption":"Settings \u2014 customisable templates for all four system emails, each with its available placeholder tokens."},{"src":"https:\/\/ps.w.org\/folio-drawbridge\/assets\/screenshot-9.png?rev=3644001","caption":"Settings \u2014 data removal policy on uninstall, the storage folder name inside the uploads directory, and the resolved encrypted storage location with its protection status."}],"raw_content":"<!--section=description-->\n<p>Folio Drawbridge lets authenticated WordPress users upload files into named <strong>vaults<\/strong>, where they are encrypted at rest using AES-256-CBC before being written to disk. Vault contents can be shared securely with external, unauthenticated recipients through a two-factor verification flow: invite email \u2192 email confirmation \u2192 one-time code. Every action across the plugin is recorded in an immutable audit log.<\/p>\n\n<h4>Key features<\/h4>\n\n<ul>\n<li><strong>Encrypted vault storage<\/strong> \u2014 AES-256-CBC with a unique per-vault key derived from a site-wide master key. Files stored with direct HTTP access blocked.<\/li>\n<li><strong>Two-factor external sharing<\/strong> \u2014 recipients receive an invite link, confirm their email, then verify a time-limited one-time code before downloading.<\/li>\n<li><strong>Multi-file and chunked upload<\/strong> \u2014 files split client-side and reassembled server-side, bypassing PHP <code>upload_max_filesize<\/code> limits.<\/li>\n<li><strong>ZIP bulk download<\/strong> \u2014 recipients can download all vault files as a single archive (requires PHP <code>ZipArchive<\/code>).<\/li>\n<li><strong>File type restrictions and per-user storage quotas<\/strong> \u2014 enforced server-side at upload time.<\/li>\n<li><strong>Role-based access<\/strong> \u2014 two tiers of non-admin access: Drawbridge Admin (full panel) and Vault User (My Vaults only).<\/li>\n<li><strong>Global share limits<\/strong> \u2014 default and maximum download counts and link expiration windows, retroactively enforceable.<\/li>\n<li><strong>OTP rate limiting<\/strong> \u2014 configurable cooldown between one-time-code requests.<\/li>\n<li><strong>Lifecycle management<\/strong> \u2014 hourly WP-Cron expires vaults and shares, sends expiry warnings, prunes stale OTPs, and cleans orphaned upload chunks.<\/li>\n<li><strong>Download notifications and expiry warnings<\/strong> \u2014 vault owners are emailed on recipient downloads and before share links expire.<\/li>\n<li><strong>Customisable email templates<\/strong> \u2014 subject and body for all four system emails with <code>{placeholder}<\/code> tokens.<\/li>\n<li><strong>Immutable audit log<\/strong> \u2014 every event logged with actor, IP, and timestamp. Filterable, sortable, exportable to CSV.<\/li>\n<li><strong>SIEM logging<\/strong> \u2014 append every audit event to a log file in JSON (NDJSON) or CSV for Splunk, Datadog, ELK, and similar tools. Written inside your uploads directory and protected from direct web access; redirectable with a <code>wp-config.php<\/code> constant.<\/li>\n<li><strong>Vault inspector<\/strong> \u2014 administrators can browse every vault, download files, edit metadata, transfer ownership, and revoke shares. All actions audited.<\/li>\n<\/ul>\n\n<h4>Part of the Folio suite<\/h4>\n\n<p>Folio Drawbridge shares a single \"Folio\" admin menu with the other Folio access and data-protection plugins when more than one is installed.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>folio-drawbridge<\/code> directory to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate <strong>Folio Drawbridge<\/strong> through the Plugins screen.<\/li>\n<li>Complete the setup checklist under <strong>Folio \u2192 Drawbridge \u2192 Dashboard \u2192 Security Status<\/strong> \u2014 generate a master encryption key (recommended: store it in <code>wp-config.php<\/code>), confirm storage is writable, and verify the lifecycle cron is scheduled.<\/li>\n<li>Grant users vault access from the <strong>Users<\/strong> tab (only WordPress administrators have access by default).<\/li>\n<\/ol>\n\n<p>Requires the PHP <code>openssl<\/code> and <code>mbstring<\/code> extensions. The optional <code>zip<\/code> extension enables ZIP bulk download.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20are%20uploaded%20files%20stored%3F\"><h3>Where are uploaded files stored?<\/h3><\/dt>\n<dd><p>Encrypted files are written to <code>wp-content\/uploads\/folio-drawbridge\/vaults\/<\/code>, protected by an <code>.htaccess<\/code> deny-all rule. Files are never served directly \u2014 every download is decrypted and streamed through PHP after authorization.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20lose%20the%20master%20encryption%20key%3F\"><h3>What happens if I lose the master encryption key?<\/h3><\/dt>\n<dd><p>Encrypted files cannot be recovered without the master key. If you define <code>FOLIO_DRAWBRIDGE_MASTER_KEY<\/code> in <code>wp-config.php<\/code>, back it up securely. Replacing the key permanently breaks decryption of existing files.<\/p><\/dd>\n<dt id=\"do%20share%20recipients%20need%20a%20wordpress%20account%3F\"><h3>Do share recipients need a WordPress account?<\/h3><\/dt>\n<dd><p>No. Recipients verify their identity with their email address and a one-time code \u2014 no account or login required.<\/p><\/dd>\n<dt id=\"where%20does%20the%20plugin%20write%20files%3F\"><h3>Where does the plugin write files?<\/h3><\/dt>\n<dd><p>Everything lives in one folder inside your uploads directory, named <code>folio-drawbridge<\/code>\nby default and changeable under Settings \u2192 Storage:<\/p>\n\n<ul>\n<li><code>vaults\/<\/code> \u2014 encrypted files<\/li>\n<li><code>chunks\/<\/code> \u2014 temporary upload staging<\/li>\n<li><code>logs\/<\/code> \u2014 SIEM export, when enabled<\/li>\n<\/ul>\n\n<p>Each is protected from direct web access. The plugin writes nowhere else.<\/p><\/dd>\n<dt id=\"can%20i%20limit%20how%20many%20times%20a%20share%20link%20is%20used%3F\"><h3>Can I limit how many times a share link is used?<\/h3><\/dt>\n<dd><p>Yes. Each share can have a download limit and an expiry date, and site-wide defaults and maximums can be configured under Settings. One download means one verified access: the recipient may retrieve every file in the vault during that session, so a limit of 1 lets them collect it once.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Multi-file upload with per-file progress.<\/li>\n<li>ZIP bulk download for recipients.<\/li>\n<li>Download notification emails to vault owners.<\/li>\n<li>Share expiry warning emails with configurable lead time.<\/li>\n<li>Customisable email templates with placeholder tokens.<\/li>\n<li>File type restriction allowlist.<\/li>\n<li>Per-user storage quotas.<\/li>\n<li>OTP request rate limiting (cooldown).<\/li>\n<li>Vault ownership transfer from the vault inspector.<\/li>\n<li>Database version tracking with automatic idempotent schema migration.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Resend share invite button on pending and active shares.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Sortable columns on all tables (server-side on paginated lists, client-side elsewhere).<\/li>\n<li>WordPress dashboard widgets for admins and vault users.<\/li>\n<li>Contextual \"apply to existing shares\" enforcement prompts in Settings.<\/li>\n<li>Expanded contextual help on every screen.<\/li>\n<li>Security: SIEM log path validation (absolute, no traversal).<\/li>\n<li>Security: Clipboard API for key copy with fallback.<\/li>\n<li>New documentation set under docs\/.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Drawbridge Admin capability for non-administrator panel access.<\/li>\n<li>Users tab redesign with search and contextual actions.<\/li>\n<li>All timestamps display in the site's configured timezone.<\/li>\n<li>SIEM logging to OS file (NDJSON or CSV).<\/li>\n<li>Inline vault expiry and share editing for admins.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Streaming encryption\/decryption in 1 MB chunks for large files.<\/li>\n<li>Chunked uploads bypassing PHP size limits.<\/li>\n<li>Download limits and link expiration settings.<\/li>\n<li>Inline share and vault expiry editing.<\/li>\n<li>Configurable OTP attempt limit.<\/li>\n<li>Server-side encryption key generator.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: encrypted vaults, two-factor sharing, immutable audit log, vault inspector, lifecycle cron.<\/li>\n<\/ul>","raw_excerpt":"Encrypted file vaults with two-factor external sharing, comprehensive audit logging, lifecycle management, and role-based vault oversight.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/349213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=349213"}],"author":[{"embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/buffcleb"}],"wp:attachment":[{"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=349213"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=349213"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=349213"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=349213"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=349213"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/dzo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=349213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}