Maester Packs
What is a pack?
Section titled “What is a pack?”A pack is a set of extra tests for Maester that someone else wrote and shares. Maester ships with its own checks; a pack adds more, so one run can also cover another product, a benchmark, or the rules of one organisation.
A pack is a folder, usually a GitHub repository, that holds:
- tests, written the same way as Maester’s own;
- helpers the tests call;
- optionally a connector to a service Maester does not know, such as Google Workspace or Okta.
Installing a pack adds its tests to your project. A run includes them when you name the pack with -Pack (or every
installed pack with -AllPacks), and its results appear in the report beside Maester’s own, marked as the pack’s.
Install-MtPack contoso/maester-google-workspaceConnect-Maester -Service Graph, CNT.GoogleWorkspaceInvoke-Maester -Pack CNTA pack is public or private, depending on the repository it lives in. Some packs also ship with Maester: they need no install and run as soon as they are turned on (see Packs that ship with Maester).
Public packs
Section titled “Public packs”A public pack lives in a public GitHub repository, so anyone can install it with Install-MtPack <owner>/<repo>.
The publisher does not need to register it anywhere or ask anyone: a public repository with a
valid pack and a release is enough.
To help people find a pack, its publisher can list it on a pack index, a site that collects packs and shows a page for each one. packs.maester.cloud is the index the Maester team runs: it reads and scans every pack before listing it, and shows what the pack checks, what it can reach and its risk. Listing is optional. An index only lists a pack: you still install it straight from the publisher’s repository, and Maester runs the same checks at install wherever you found it.
When you install a public pack, Maester sends one anonymous event (the pack’s source and commit, and a random
installation ID) so installs can be counted. Set MAESTER_DISABLE_TELEMETRY to 1 to turn that off.
Private packs
Section titled “Private packs”A private pack lives in a private or internal GitHub repository. Only people who can read that repository can install it, which makes it the way to share tests inside one company: checks for your own policies, naming rules or internal systems that should not be published. Anyone you give access to the repository, such as a partner or a customer, can install it as well.
Install it like any other pack. Install-MtPack, Update-MtPack and Restore-MtPack need a GitHub sign-in that
can read the repository, and use the first of these that can:
-Token, aSecureString, for a script that reads a token from a vault. When you pass it, nothing else is tried.- The Maester session’s GitHub sign-in, after
Connect-MtGitHub, when it is to github.com. The Maester GitHub App must be able to read the pack’s repository. - The GitHub CLI. When
ghis installed and signed in, Maester asks it for a token (gh auth token) at the moment of each request and does not keep it. GH_TOKEN, thenGITHUB_TOKEN, the environment variables a pipeline sets.
On your own computer, sign in to the GitHub CLI once and there is nothing to set:
gh auth loginInstall-MtPack contoso/maester-internal-checksWith a token from a vault:
Install-MtPack contoso/maester-internal-checks -Token (Get-Secret -Name PackReadToken)Whichever way it gets it, Maester sends the token to api.github.com only and does not store it. Use a token
that can only read this one repository: a fine-grained token with read-only Contents.
A private pack goes through the same checks as a public one, and is pinned in the lock file the same way. What is different:
-
It is never listed on packs.maester.cloud, and cannot be published there.
-
Maester is never told which pack it is: there is no install event, and run telemetry never names it. A run’s totals still count its tests (how many ran, passed and failed), unless telemetry is off (
MAESTER_DISABLE_TELEMETRYset to1). -
A pipeline needs a token too. In GitHub Actions the workflow’s own
GITHUB_TOKENreads only the repository the workflow runs in, so a pack in another private repository needs a token that can read that repository. Give it to the restore step only, not to the whole job:- name: Restore packsshell: pwshenv:GH_TOKEN: ${{ secrets.PACK_READ_TOKEN }}run: Restore-MtPack
A pack can also be installed from a local folder (Install-MtPack ./my-pack), which suits a pack you are still
writing or one you keep outside GitHub. It is treated like a private pack: Maester is never told which pack it is.
Installing a pack
Section titled “Installing a pack”Install-MtPack takes the pack’s GitHub repository (owner/repo, owner/repo/folder, owner/repo@ref or a
github.com URL) or a local folder. Before anything is saved, Maester:
- downloads the pack and reads it without running any of its code: its manifest, every file and what its scripts call;
- checks that the release is at least 72 hours old (the cooldown);
- checks your pack policy and the signed blocklist;
- saves the PowerShell Gallery modules the pack declares, at their exact versions, into its own store;
- shows you what the pack can reach, its risk and anything the scan found, and asks you to approve it.
Google Workspace checks contoso.google-workspace 1.2.0 Source github.com/contoso/maester-google-workspace @ 3f9c2e1 (ref v1.2.0) Publisher contoso Adds 14 tests (MP.CNT.*) and the "Google Workspace" connector Reaches CNT.GoogleWorkspace, admin.googleapis.com Microsoft no extra Graph scopes Risk LOW: text files only; no findings from the content checksThe approved files go into a read-only store under ~/.maester/packs (or MAESTER_PACK_HOME), named by their
digest, and the pack is recorded in two files beside your maester-config.json:
maester-config.jsongets aPacksentry:{ "Id": "contoso.google-workspace", "Source": "contoso/maester-google-workspace", "Version": "1.2.0" }.maester-packs.lock.jsonrecords the commit, the digest of the files, the test IDs, the risk you accepted and the digest of every module.
Commit both. Without a project config, packs are installed for your user, in ~/.maester.
| Command | What it does |
|---|---|
Install-MtPack <source> | Installs a pack, after the checks above. -Version picks a release, -IncludeRecent one newer than the cooldown. |
Get-MtPack | Lists the packs this folder runs and whether each can run (Status, Reason). |
Update-MtPack [<id>] | Installs each pack’s newest release that has met the cooldown, showing what changed since you approved it. |
Restore-MtPack | Installs exactly what the lock file records, on another computer or in a pipeline. Nothing is asked: the lock file is the approval. |
Uninstall-MtPack <id> | Removes the pack from the lock file and the config. |
Get-MtConnector | Lists the services that installed packs connect to, and whether each is connected. |
In a pipeline
Section titled “In a pipeline”Commit maester-config.json and maester-packs.lock.json, then restore before the run:
Restore-MtPackInvoke-Maester -AllPacks -NonInteractiveTo install without a prompt, say which risk you accept: Install-MtPack contoso/pack -NonInteractive -AcceptRisk Medium.
Running pack tests
Section titled “Running pack tests”Installing a pack does not add its tests to every run. Invoke-Maester runs an installed pack when you name it
with -Pack (by its code or ID), when -TestId names one of its tests, when you pass -AllPacks, or when the
config turns it on with "Enabled": true. A pack’s tests have IDs MP.<code>.<n>, so -TestId 'MP.CNT.*'
runs one pack’s tests. In every case only packs whose files still match the lock file run. -SkipPack runs no
pack, and -PackLock names another lock file.
{ "Packs": [ { "Id": "contoso.google-workspace", "Enabled": true } ]}A pack that cannot run never stops the run. Its tests are reported as not run, with the reason:
PackUnavailable (not on this computer, or its files changed), PackNotAllowed, PackBlocked or
PackLoadFailed (see reason codes).
In the results, a pack’s rows have Source Custom and a Package field with
the pack’s ID, version, commit and publisher.
To turn a pack off without uninstalling it:
{ "Packs": [ { "Id": "contoso.google-workspace", "Enabled": false } ]}Choosing which packs run
Section titled “Choosing which packs run”-Pack runs only the packs you name, by pack ID or code, with * wildcards:
Invoke-Maester -Pack ZTA # Maester's tests and the Zero Trust Assessment packInvoke-Maester -Pack ZTA -SkipBuiltIn # the Zero Trust Assessment pack onlyInvoke-Maester -Pack CNT, maester.* # two codes or IDsInvoke-Maester -AllPacks # every installed packA pack you name runs even if it is off by default or turned off in the config (-AllPacks still leaves out the
packs the config turns off), and its long-running and
preview tests run without -IncludeLongRunning or -IncludePreview. Packs you do not name don’t run in that
run. The other tests are not affected: select them with -TestId, -Suite or the other selectors as usual, or
leave them out with -SkipBuiltIn. The config equivalent is Selection.Pack:
{ "Selection": { "Pack": [ "ZTA" ] }}Connecting to a pack’s service
Section titled “Connecting to a pack’s service”A pack with a connector adds a service, such as CNT.GoogleWorkspace. Tests that need it are skipped while it
is not connected, with the command that connects it:
Connect-Maester -Service Graph, CNT.GoogleWorkspace -ServiceSetting @{ 'CNT.GoogleWorkspace' = @{ Domain = 'contoso.com' } }Test-MtConnection -Service CNT.GoogleWorkspaceA connector’s settings come from -ServiceSetting, then from environment variables named
MAESTER_<SERVICE>_<SETTING> (for example MAESTER_CNT_GOOGLEWORKSPACE_DOMAIN), then from the config:
{ "Connections": { "CNT.GoogleWorkspace": { "Domain": "contoso.com" } }}A setting whose name looks like a secret (Secret, Password, Token, Key, Credential, Certificate) is
never read from the config: pass it with -ServiceSetting or an environment variable. Pack services are never
part of -Service All. Disconnect-Maester disconnects them too.
Packs that ship with Maester
Section titled “Packs that ship with Maester”Packs that ship with Maester are part of the module, in its packs folder. They are trusted as the module is:
they need no lock entry and no approval. Each one says whether it is on by default; turn one on or off with its
Packs entry in the config. If a pack that ships with Maester uses PowerShell Gallery modules, run
Install-MtPack <id> once to save them and pin their digests. Their test IDs have no MP. prefix: the Zero
Trust Assessment pack’s tests are ZTA.<n>.
Writing a pack
Section titled “Writing a pack”See Writing a pack. To learn what Maester checks and why, see Pack security.