aethercert
Documentation

Target Registry authoring reference

How a registry package is put together - parameters, operations, the deployment flow, conditions, state, PowerShell and rollback - and how to start one from JSON or with an AI assistant over MCP.

This page is for publishers. It describes the model behind Store > Target Registry > New Registry Target (schema registry.aethercert.com/v2). If you only install packages, Target Registry is all you need.

The parts of a package

PartWhat it is
ParametersWhat the installer fills in per deploy target: text, number, yes/no, a list of texts, or a secret.
ConnectionWhere REST and TLS operations connect - a host (optionally a port and "accept a self-signed certificate"), a local socket, or nothing.
AuthenticationHow the agent signs in once for every REST operation: HTTP Basic, an API key, OAuth2 client credentials, or a session login.
OperationsWhat the target can do. Each has a name, a capability (what it does), and one way of running: REST, file, TLS check, service, or PowerShell.
Deployment flowThe steps that run, top to bottom. One operation can run in more than one step.
RollbackOptional steps that try to undo a failed deployment.

Two things are derived for you and never typed: the package's capabilities (the union of its operations' capabilities, a label for people browsing the Store) and its permissions (exactly what the operations need - publishing refuses both less and more).

References

Values reach an operation through references written as {{ root.path }}. There are no expressions or functions - a reference is replaced by its value, nothing more.

RootWhat it holds
config.<key>A parameter the installer filled in.
secret.<key>A secret parameter. Only usable in authentication, REST headers, bodies and query values, and secret script parameters - never in a path, a file, a condition or an output.
state.<key>A value an earlier step wrote (see State).
certificate, chain, privateKey, pfxThe key material being deployed (PEM, .base64, .derBase64; pfx and pfx.password). Using one gives the operation that material - and nothing else.
job.*Facts about the job: id, commonName, domains, isRenewal.

A secret never appears in the package itself - only the reference does. The installer's value is stored encrypted and redacted from every error.

State

An operation can declare outputs: values it picks from a REST response ($.id, $.data.name, or $status for the HTTP status code) or from the JSON object a PowerShell operation prints on its last line. Each output is written to state.<name> after the step succeeds, and later steps read it - in a path, a body, a condition or a PowerShell parameter.

A step can only read state from steps above it; the editor offers nothing else and publishing checks it. A state value that was never written - because the step that writes it was skipped - is empty.

Conditions

A step can run only when a condition holds: one value, one comparison. A step whose condition is false is shown as skipped and the flow continues.

Value"has a value""is empty or not set""is" "" / "is not" ""
not set / never writtennoyesis ""
"" (empty text)noyesis ""
"x"yesnois not ""
falseyesnocompared as "false"
0yesnocompared as "0"
empty list []yes (present, but empty)nonot allowed - use "contains"
["a"]yesnonot allowed - use "contains"
  • "is on" / "is off" exist only for yes/no parameters; a value that is not set counts as off.
  • "contains" exists only for lists, and is false on an empty or unset list.
  • Recommendation: for an optional text where the content matters (a chain path, a service name, a previous thumbprint), use "is not" with an empty value rather than "has a value". It says exactly what you mean.

PowerShell scripts

Every PowerShell operation is a script your package defines - community publishers included. Declare each value the script reads as a parameter (type, required, allowed values, pattern, length) and pass values with with: each value is a literal or exactly one reference, checked against the parameter before the script starts. Nothing is ever pasted into script source. The operation needs the local.powershell: script permission, which the editor derives for you.

Your script runs wherever the installing organization's registry policy allows your package. Community packages are off by default in every organization, so a community package reaches organizations that chose to enable community targets.

A script reads its parameters as $env:AC_PARAM_<name>. With the certificate as material it also gets $env:AC_CERT_THUMBPRINT, $env:AC_CERT_COMMON_NAME and $env:AC_CERT_SANS; with certificate and private key, $env:AC_PFX_PATH and $env:AC_PFX_PASSWORD - a temporary PFX file with restricted access that is deleted afterwards, even when the script fails. Print outputs as one JSON object on the last line:

$ErrorActionPreference = 'Stop'
Set-AdfsSslCertificate -Thumbprint $env:AC_PARAM_thumbprint
@{ thumbprint = $env:AC_PARAM_thumbprint } | ConvertTo-Json -Compress

What the script boundary does and does not promise

The script arrives on standard input, never on the command line, and its source contains no secrets. Values in environment variables are still readable inside the process and by sufficiently privileged processes on the host (SYSTEM, administrators, debuggers). The host is trusted - this narrows what a package can touch, it does not hide anything from the machine's own administrators.

Rollback

Define a rollback when the target has a reliable previous state to return to - for example the certificate an IIS binding used before, which iis.setBindingCertificate returns as previousThumbprint.

  • It runs only when the deployment fails after at least one step succeeded.
  • Its steps run in order; a failing one does not stop the others.
  • It can read every state value the deployment wrote. Guard each step - e.g. run the restore only if state.previousThumbprint "is not" "" - so it does nothing when there was nothing to restore.
  • It is best effort, not a transaction. Nothing is guaranteed to come back, and the deployment's own error always stays the job's result. The rollback outcome (succeeded, partial, failed) is logged next to it.
  • Order the deployment so destructive steps come last - remove the old certificate only after the new one is bound and verified, so a rollback still has something to bind.

Leave the rollback empty when there is no reliable previous state; a rollback that guesses is worse than none.

Capabilities

Pick a capability from the catalogue (certificate, private key, binding, configuration, service, deployment) or name your own, such as windowsRole.certificateBind. The catalogue's own namespaces only accept catalogue names, to catch typos. A capability is a label: what an operation may do is decided by how it runs, the material it declares and its permissions - never by its capability name.

Starting from JSON

New Registry Target offers three ways to start:

  • Create manually opens the form editor described above.
  • Import file opens a manifest .json file. The file is read in your browser; nothing is uploaded until you save.
  • Paste JSON takes a DeploymentTarget manifest (registry.aethercert.com/v2) you copied from somewhere else - for example one an AI assistant wrote, or one you exported from target discovery.

Imported and pasted manifests open in the JSON editor. A manifest can be up to 256 KiB. The check runs on the server as you type, and Save draft keeps your work even while the manifest still has errors. Once the manifest passes the schema check, Continue in form opens it in the form editor, and Edit as JSON goes back. Releasing always happens from the form's Review & publish step, with the same checks as every other target.

What the check stages mean

The check runs four stages in order. A stage runs only when the stages before it passed; otherwise it is shown as skipped, so one mistake is not reported twice.

StageWhat it checksWhat you see
ParsingThat the text is one valid JSON object, within the size limit.The line and column of a syntax error. A key that appears twice in one object is a warning: JSON keeps only the last value.
SchemaThe structure: required fields, unknown fields, types, allowed values.Every structural problem at once, each with the path of the field, for example operations.bind.rest.method.
SemanticThe rules between fields: references to declared parameters and state, executors and their payloads, workflows, conditions.The first problem found, with its path.
SecuritySecrets, key material, permissions, trust levels, literal hosts and paths, PowerShell scripts.The first problem found, with its path.

The semantic and security stages stop at the first problem, exactly like the agent does. When one of them fails, the other is shown as skipped; fix the problem and check again. Each issue carries a code, such as SCHEMA_UNKNOWN_FIELD or PERMISSION_MISSING, that names the kind of problem.

One rule is softer while you work: a permission that no operation needs is a warning in a draft. It is still refused when you release, because a package may declare exactly the permissions its operations need - no less and no more.

Next to the issues, the security summary lists what the target would be allowed to do: how it runs, which hosts it connects to, whether it receives the private key, which files it writes, whether it controls a service or runs PowerShell scripts, and any text that looks like a hard-coded password or token. The summary is informational: it helps whoever releases the target, and it never decides whether the manifest is valid. It appears once the manifest passes the semantic and security stages.

Draft provenance

Every draft shows where it came from, in the In progress list and in the editor header, for example Source: AI generated · Status: Draft.

BadgeMeaning
ManualBuilt in the form editor.
ImportedImported from a file or pasted as JSON.
AI generatedYou declared that an AI wrote it, or an AI assistant created it over MCP.

aethercert sets the source when the draft is first saved, and it never changes after that. Editing an AI-generated draft in the form keeps it AI-generated. When you paste or import a manifest, tick This manifest was generated by an AI if that is the case, and optionally name the AI provider. You can mark a draft as AI-generated, but nothing can mark an AI-generated or imported draft as manual.

Imported and AI-generated drafts show a notice in the review step. Before you release one, check what each operation does and what it may access - the security summary lists it. The released version keeps a record of how it was authored and who released it.

Connecting an AI assistant over MCP

An AI assistant that supports the Model Context Protocol (MCP) can work with the Target Registry for you: read the schema and the vocabulary, look at existing targets as examples, check a manifest it wrote, and save it as a new draft for you to review.

Endpoint: https://api.aethercert.com/api/mcp

Add this URL as a remote MCP server in your assistant. The assistant must support MCP authorization with OAuth and Client ID Metadata Documents; an assistant that only supports dynamic client registration, or that runs as a web page in your browser, cannot connect.

Allowing the connection

The first time the assistant connects, it opens the aethercert dashboard in your browser:

  1. Sign in with your second factor (or a passkey). If you normally use an MSP portal domain, sign in on the dashboard address the assistant opens.
  2. Choose an organization. The assistant works in exactly the organization you choose, and only in that one.
  3. Review and allow. The consent page shows the assistant's name - which is the assistant's own claim - and the domain that identifies it. aethercert does not verify who runs that domain, so allow it only if you trust it. Then choose Allow or Deny.

The assistant can ask for these permissions:

PermissionWhat it allows
Read the Target RegistryRead the schema and the vocabulary, search and read the targets you can see, and check manifests.
Create draftsAdditionally save a manifest as a new draft in the chosen organization, marked AI-generated. Needs the admin or owner role there. If you do not have it, only read access is granted.
Stay connectedKeep working without asking you again, for up to 30 days.

An AI assistant can never release a target

The assistant can only create new drafts. It cannot change or discard an existing draft, and it can never release, publish, install or configure a target. Every draft it creates is marked AI generated and waits in In progress until a person in your organization reviews it and releases it - or discards it. Treat its manifest like code from an unknown author: check the operations and permissions before you release.

The assistant gets a link to each draft it creates. A draft it creates for a package that already has a draft is refused, so it never overwrites work in progress. Your organization can receive at most 20 drafts per hour this way.

How long a connection lasts

A connection ends by itself after 7 days without use, and after 30 days at the latest. The assistant then asks you to allow it again. If you are removed from the organization, the connection stops working at once.

Revoking a connection

Settings > Connected apps lists every assistant you connected, with its organization, its permissions and when it was last used. Revoke ends a connection immediately: the assistant's next request is refused.

Signing out everywhere, signing out your other devices, and resetting your password also disconnect every connected assistant.

On this page