-
Notifications
You must be signed in to change notification settings - Fork 106
Tag Based Encryption
Tag-based encryption lets you encrypt a whole class of posts (e.g. "drafts", "diary", "client-X") with a shared password by tagging them — no per-post password: field needed.
In _config.yml:
encrypt:
tags:
- { name: diary, password: 'diary-secret' }
- { name: drafts, password: 'draft-secret' }
- { name: client-acme, password: 'acme-2024' }In a post:
---
title: Today's entry
date: 2024-01-01
tags:
- diary
- personal
---
This post is tagged `diary`, so it's encrypted with `diary-secret`.
<!-- more -->
Private content.No password: field in the front matter. The plugin scans post.tags, finds diary, looks it up in the registry, and uses diary-secret.
-
Front-matter
password:wins over everything. If you setpassword: fooin front matter, the post usesfooregardless of tags. -
First matching tag. If a post has multiple tags that all appear in the registry, the first one defined in
_config.ymlwins (registry order). -
No match → not encrypted. A post tagged
personal(not in the registry) and with nopassword:in front matter is published in plaintext.
If a post should normally be encrypted by tag but you want this one to be public:
---
title: Public exception
tags:
- diary
password: "" # explicit empty string disables encryption
---Empty-string password: short-circuits encryption even if the tag would otherwise apply.
Hexo materializes post.tags as a Warehouse Query, not a plain array. The query has .toArray() and .forEach() methods, but Array.isArray(post.tags) returns false. A naive Array.isArray check would silently skip tag matching and publish the post in plaintext.
This was a real bug introduced during the v4 redesign and caught by cross-model audit before merge. The current implementation in src/server/index.js#normalizePostTags accepts any of:
-
Array.isArray(tags)— plain JS arrays (test fixtures) -
tags.toArray()— Warehouse Query (real Hexo posts; preferred when present) -
tags.forEach()— fallback for unusual collection shapes
There are 4 server unit tests + 2 e2e tests guarding this codepath. If you're a plugin contributor: please don't replace the toArray / forEach checks with Array.isArray.
# _config.yml
encrypt:
tags:
- { name: diary, password: 'diary-secret' }---
title: Important Diary Entry
tags:
- diary
password: 'override-this-one' # per-post wins; encrypted with override-this-one
---Per-post password: always wins over the tag registry.
The tags array on _config.yml#encrypt is site-config-only. Front-matter tags is the post's own tag list (a different concept), and the tag registry is not picked up from front matter to avoid Hexo's Warehouse Query issues during deep-merge — see src/server/config.js#POST_KNOWN_KEYS vs KNOWN_KEYS.
/demo/tag/ — tagged ThemeDemos, password hello.