Skip to content

Registration notifications

When a developer registers an agent by running the SDK, nobody has to watch a queue. The gateway e-mails the developer a pending receipt, e-mails the workspace administrators that a review is needed, and e-mails the developer again when a decision is recorded and when the registration is approved or denied. Every message is sent from the platform’s no-reply mailbox (SMTP_FROM_EMAIL), the same sender as every other platform e-mail, and carries no credentials. This page describes the messages, the two-run route they support, the sender, and how to verify delivery.

The developer’s address is the registering e-mail the gateway recorded on the first run. Name the registering developer explicitly with DEEPINTSHIELD_REGISTERED_BY or the constructor argument registered_by; it needs SDK 3.2.0 or newer. The gateway maps the address to a person in the workspace directory, created just in time when unknown and shown by the address, and notifies it. The address is not verified and grants nothing. When neither is set, an e-mail-shaped requester is only an advisory hint, which the gateway uses only for a person the organization placed in the workspace and ignores otherwise. Older SDKs still register and still trigger the administrator messages. Without a confirmed registering address, the developer messages fall back to the agent’s accountable owner when one is known and are otherwise not sent.

EventRecipientSubjectContent
Pending receipt (registration.pending_receipt)The registering address the gateway recordedDeepintShield: registration pending for <agent>The line the SDK printed: the registration reference, the runtime-key thumbprint (SHA256:…) only when a key is enrolled, and the instruction to contact an administrator. It ends with If you did not register this agent, tell your administrator. No review link, no call to action. One receipt per enrolment cycle. It is held for up to 45 seconds only while a runtime key can still arrive, so that key’s thumbprint can be included. Send limits apply; see Sender and delivery settings.
Review needed (registration.needs_review)Workspace administrators and the tenant’s organization owners and administrators, excluding the registrant and the agent’s accountable ownerDeepintShield: agent <agent> needs registration reviewA details table (agent, workspace, framework, the reporting key’s ID, first seen, runtime-key thumbprint, reference) and a Review registration button that opens /workspace/agentic-new/registry?review_registration=<id>. Sent again when a VK-trusted agent later presents verified proof.
Decision recorded (registration.decision_recorded)The developerDeepintShield: decision recorded for <agent>An administrator approved the agent for deferred activation. The next run of the unchanged script activates it: with gateway exchange, from the same machine and runtime key; in direct mode, when it signs in with the agent’s own identity. A code change before that run sends it back to review.
Approved (registration.approved)The developerDeepintShield: <agent> approvedWho approved the agent and when, and that the next run uses the approved profile. No secrets, no review link.
Denied (registration.denied)The developerDeepintShield: <agent> registration deniedRegistration denied by an administrator. Reference <id>. and the reviewer’s note when one was entered.
Recorded decision stale (registration.decision_stale)Administrators and the developerDeepintShield: recorded decision for <agent> is staleWhy the recorded decision no longer applies (the code, scan, identity, runtime key, provider, owner, reporting key or reviewer changed, or it expired). Administrators get a Review again button; the developer is told that the next run will not activate the agent.

Developer messages never contain a review link, an approval action, or any secret. Administrator messages contain the review link and a details table; the reporting key appears by its ID, never by its value. The list of administrators is resolved when the message is queued: active workspace members with the admin role plus the tenant’s organization owners and administrators, de-duplicated by e-mail and capped at 25 recipients. A single-administrator workspace in which the only administrator is also the registrant receives the pending receipt but no review-needed message, because the registrant is always excluded from the approver list.

Withdrawing a recorded decision sends nothing. It is an administrator’s own action, and the review shows the result immediately.

The developer and the administrator each act once; nobody waits on the other in real time.

  1. Developer, run 1. Run the agent with four settings: DEEPINTSHIELD_BASE_URL, DEEPINTSHIELD_VIRTUAL_KEY, DEEPINTSHIELD_AGENT_NAME and DEEPINTSHIELD_REGISTERED_BY (constructor argument registered_by). The SDK captures the source, enrols its runtime key when the workspace uses Entra gateway runtime authentication, and prints one line:

    Registration pending. Reference <registration id> · runtime key SHA256:<thumbprint>. Contact your administrator. You will be notified at <email>.

    The runtime-key clause is omitted when no key was enrolled, and the closing sentence, You will be notified at <email>., appears only when the gateway confirmed the address. The developer is not shown a review link and cannot approve. DEEPINTSHIELD_REGISTERED_BY is the explicit way to name the registering developer. The gateway maps it to a person in the workspace directory and notifies it; it is not verified and grants nothing. One registration keeps its first address: a different address on a later run is refused with registration_requester_mismatch. When it is not set, an e-mail-shaped requester is only an advisory hint. The gateway uses it only for a person the organization placed in the workspace and ignores it otherwise, without refusing the run; the registration is then captured without a registering address.

  2. Administrator, one sitting. The review-needed e-mail opens the registration. The review shows Registered by <email> with the note Given by the developer with the virtual key. Not verified. It proposes that person as the owner; the administrator selects Confirm owner or chooses another person. The administrator creates or links the identity, selects Authorize runtime key for the key whose thumbprint the developer received, reviews the code scan and selects the tool actions, then selects Approve now, activates on the agent’s next run and confirms with Approve now · activates on next run. The Decision recorded card lists the actions that activation will grant. The reviewer cannot be the agent’s accountable owner, nor an administrator who registered the agent with their own sign-in e-mail. The developer receives the decision-recorded e-mail.

  3. Developer, run 2. The unchanged script runs again. The gateway verifies the runtime key and identity, applies the recorded decision before answering, and the whole agent executes, because the decision grants every action the administrator selected; the developer receives the approval e-mail. A script changed after the decision was recorded fails closed into a new review, and the stale-decision e-mail goes to the administrators and the developer.

Gateways without deferred activation still support the earlier three-run route: authorize the key, run to collect proof, approve, run again. An immediate approval sends the approval e-mail as soon as the administrator confirms it. Workspaces whose blueprint scan mode is static_and_model activate on the run after the model scan completes. See Agentic for the review itself and Agent workload identity for the runtime-key steps.

Every identity type follows the same route: run 1, one review sitting, then the next run. What the sitting contains and what the developer needs before run 2 depend on how the agent proves who it is.

Identity typeWhat the administrator does in the sittingWhat the developer needs before run 2RunsServer runs
Plain virtual key (VK-trusted)Confirms the owner, reviews code and tools, and selects Approve as VK-trusted (development only), with or without a declared identity. The option is offered only while Allow VK-trusted approvals (development only) is on (Policy & Access → Runtime policy → Registration review). Keep that setting off in production workspaces. A VK-trusted approval is never recorded for later and never automatic.Nothing new: the four settings and pip install deepintshield.TwoNo. Where server runs reach every workspace (*, the default), the program runs on the developer’s machine after its server run ends, and in this release that first local run asks for one more code review. In a workspace listed for server runs the agent cannot run (managed_gateway_runtime_required).
Microsoft Entra with gateway exchangeConfirms the owner, creates or links the identity, authorizes the runtime key by its thumbprint, reviews code and tools, and selects Approve now, activates on the agent’s next run.The four settings and pip install 'deepintshield[runtime]' from run 1, on the same machine.Two. Three when no runtime key arrived on run 1.Yes. It is the only identity type that can finish a server run.
Microsoft Entra directConfirms the owner, declares or creates the identity, reviews code and tools, and records the decision. There is no runtime key to authorize.An Azure host whose identity the agent blueprint trusts, the four settings and pip install 'deepintshield[azure]'. It never works from a laptop.Two, on an Azure hostNo, as for a plain virtual key.
Generic OIDC: Okta, Auth0, Keycloak and any issuerConfirms the owner, declares the agent’s token subject, reviews code and tools, and records the decision.The agent’s own client credential on the machine: OIDC_CLIENT_ID plus OIDC_CLIENT_SECRET, or OIDC_CLIENT_AUTH_METHOD=private_key_jwt with OIDC_PRIVATE_KEY_FILE.Two, only when that credential is on the machine before run 2No, as for a plain virtual key.
ZeroID (experimental)The provider is configured through the API beforehand. In the sitting, the same steps as Generic OIDC.ZEROID_SUBJECT_TOKEN and ZEROID_EXCHANGE_ENDPOINT.Two, when both are set before run 2No, as for a plain virtual key.
SPIFFENot available for registration. A SPIFFE provider cannot be created.Not applicableNot applicableNot applicable

For Generic OIDC, the issuer and its signing keys must be reachable at a public https address on port 443. A Keycloak on a private network therefore cannot be verified. The gateway accepts tokens that live one hour or less; set the token lifetime at the issuer. The subject to declare depends on the issuer: for Okta it is the client id, for Auth0 <client id>@clients, and for Keycloak the service-account user id.

An administrator who registered an agent with their own sign-in e-mail cannot record its decision. While Require a separate reviewer for immediate approvals is on, they cannot approve it at all. In a one-person workspace, approve immediately after the agent’s next run (three runs), or register the agent with a different e-mail.

Registration e-mails are sent from the platform no-reply mailbox (SMTP_FROM_EMAIL) through the gateway’s platform SMTP settings. These are the same settings every other platform e-mail uses, such as e-mail verification, invitations, alerts and billing notices.

VariableDefaultPurpose
SMTP_HOSTunsetSMTP host of the platform mailbox.
SMTP_PORT587465 uses implicit TLS; other ports use STARTTLS when the server offers it.
SMTP_USERNAMEunsetMailbox login. Empty means no SMTP AUTH.
SMTP_PASSWORDunsetMailbox password. Keep it in a secret store, never in a tracked file.
SMTP_FROM_EMAILunsetThe From address of every platform e-mail: the no-reply mailbox.
SMTP_FROM_NAMEDeepintShieldDisplay name of the sender; registration e-mails use DeepintShield when it is unset.

With SMTP_FROM_EMAIL=no-reply@deepintshield.com and the default display name, recipients see From: DeepintShield <no-reply@deepintshield.com>. No Reply-To header is set.

When SMTP is not configured (no SMTP_HOST, or no SMTP_FROM_EMAIL), nothing fails: registration proceeds, the messages stay queued, and the gateway logs a warning. They are sent once SMTP is configured and the gateway has restarted with those settings.

On DeepIntShield Cloud the mailbox is operated by the service team. A self-managed gateway already carries these settings wherever its platform e-mail is configured: the service’s environment and secret store on Cloud Run or Kubernetes, or the .env file of the local compose stack. Registration e-mail adds no variable, secret or template value to a deployment.

Review links use the deployment’s public origin: SMTP_DASHBOARD_URL, then APP_BASE_URL, then DASHBOARD_URL, then http://localhost:8080.

The following gateway variables are optional. They tune delivery and the lifetime of a recorded decision; none of them changes the sender.

VariableDefaultPurpose
AGENTIC_NOTIFY_ENABLEDtruefalse parks delivery: messages are still queued, and this gateway process sends none of them.
AGENTIC_NOTIFY_SWEEP_INTERVAL60s (15s to 10m)How often the dispatcher looks for queued messages.
AGENTIC_NOTIFY_WORKERS2 (1 to 8)Concurrent sends per gateway process.
AGENTIC_NOTIFY_SEND_TIMEOUT10s (2s to 60s)Per-message SMTP timeout.
AGENTIC_NOTIFY_MAX_PER_REGISTRATION_PER_HOUR6 (1 to 100)Storm guard: how many messages one registration may queue for one recipient per hour. Messages beyond it are skipped.
AGENTIC_DEFERRED_DECISION_TTL_HOURS168 (1 to 720)How long a recorded decision waits for the agent’s next run before it expires.

All of them are read when the gateway starts. A malformed value falls back to its default, and so does an out-of-range value, except AGENTIC_DEFERRED_DECISION_TTL_HOURS, which is clamped to its bounds.

The pending receipt has two send limits of its own. At most 20 distinct registering addresses per reporting Virtual Key, and at most 20 receipts per address across the workspace, are queued in any 24 hours. Over a limit the registration is still captured and the address recorded; only that receipt is not queued, and the gateway logs one warning line. Review requests and the approval, denial and decision notices are not subject to these limits. The limits are code-level tunables, AGENTIC_NOTIFY_MAX_ADDRESSES_PER_KEY_PER_DAY and AGENTIC_NOTIFY_MAX_RECEIPTS_PER_ADDRESS_PER_DAY (default 20 each, 1 to 10000). Deployment templates do not set them.

  • Each message is written to a durable outbox (agenticnew_notifications) in the same database transaction as the registration capture, review, denial or recorded decision. If the transaction rolls back, no message exists.
  • Delivery is attempted right after the commit and again by a periodic sweep (AGENTIC_NOTIFY_SWEEP_INTERVAL, 60 seconds by default). On Cloud Run, where an idle instance has no CPU, an administrator opening the registrations list, the work queue or the delivery log also triggers an attempt, at most once every 30 seconds, so a message queued by the last request before scale-to-zero is sent on the next inbound request.
  • A failed send retries with exponential backoff, from 30 seconds up to 8 hours, for at most eight attempts and is then marked failed. A recipient the mail server rejects outright fails immediately. The error text is kept without credentials.
  • Messages are idempotent per event, registration, revision and recipient: repeated sightings, duplicate reviews or a restarted sweep cannot produce duplicates.
  • Nothing runs on the authorization path. /decide, runtime proof and tool authorization never queue or send e-mail; only control-plane and pending registration requests queue messages, and sending happens after they commit.
  • Sent and failed rows are removed by the Agentic evidence retention sweep (DEEPINTSHIELD_AGENTIC_RETENTION_DAYS). Messages that are still queued are never pruned.

If you run the local compose stack from the repository checkout, start the gateway with the development mail sink:

Terminal window
python3 deployment/restart-local-gateway.py --mail-sink

The overlay adds a Mailpit container and points that dev gateway’s platform SMTP_* settings at it on port 1025, without TLS or credentials; the sender stays the platform no-reply mailbox. All platform e-mail of that dev stack then lands in Mailpit, not only registration e-mail, and none of it reaches a real mailbox. Run an unregistered agent once, then open http://127.0.0.1:8025 (or GET http://127.0.0.1:8025/api/v1/messages) to read the pending receipt and the review-needed message. The stack’s .env file is not changed and the flag is never written into the persisted compose defaults, so recreating the gateway without --mail-sink returns it to the SMTP settings in .env. The sink is bound to the loopback interface only.

SymptomCheck next
No e-mail arrivedOpen GET /api/agentic-new/registry/registrations/{id}/notifications with an administrator session. Each row shows the event, the recipient kind, the masked recipient (a***@domain), status, attempts, next_attempt_at, sent_at and last_error; bodies are never returned. pending with a future next_attempt_at is a retry in progress; failed names the SMTP error.
Every row stays pendingEither the platform SMTP settings are incomplete (SMTP_HOST and SMTP_FROM_EMAIL must both be set; the gateway log says SMTP is not configured, and no other platform e-mail is sent either), or AGENTIC_NOTIFY_ENABLED=false parks delivery for this gateway process. Queued messages are kept and are sent once SMTP is configured, or delivery is enabled again, and the gateway has restarted.
The developer received nothing but administrators didThe gateway recorded no registering address: the run did not set DEEPINTSHIELD_REGISTERED_BY (SDK 3.2.0 or newer) and an e-mail-shaped requester was ignored because it does not belong to a person the organization placed in the workspace, or the registration was captured by an older SDK and has no accountable owner yet. A send limit can also skip the pending receipt. The SDK line then ends without You will be notified at <email>. Once recorded, the registering address is stable for the registration.
Administrators received nothingThe only administrator is the registrant or the agent’s owner, so nobody remained on the approver list.
The mail server rejects the message or rewrites the senderThe SMTP account does not accept SMTP_FROM_EMAIL as its sender. Every platform e-mail uses the same settings, so correct the platform SMTP settings; there is no separate sender for registration e-mail.
Messages land in spamPublish SPF and DKIM for the sending domain and align the From domain with the authenticated mailbox.
failed after eight attemptsFix the SMTP settings, then trigger a fresh event such as the next review or denial. Failed rows are not resent automatically.