# I Tried to Package an Agentforce Agent—and Discovered It Is Really a Lifecycle Problem

Installing an Apex class from a managed package is straightforward. Installing a complete, customer-ready Agentforce agent is a very different problem.

That difference became clear while I was experimenting with how an ISV could distribute Agentforce capabilities through a second-generation managed package (2GP).

My original expectation was simple:

```text
Install managed package
        ↓
Working agent
```

What I discovered looked more like this:

```text
Install managed package
        ↓
Install stable capabilities
        ↓
Configure subscriber environment
        ↓
Build customer-specific agent
        ↓
Compile and publish
        ↓
Test and activate
        ↓
Working agent
```

That small-looking difference changed how I think about Agentforce distribution.

> **The package installs the capabilities. A separate provisioning lifecycle assembles those capabilities into a customer-specific agent.**

Once I understood that, the challenge stopped looking like a packaging problem. It became an agent lifecycle architecture problem.

## Why I started exploring this

Imagine that you are an ISV shipping a Salesforce application. Your package already contains the components an agent needs: Apex actions, Flows, permission sets, configuration and business logic.

The natural next question is: can the package also deliver the agent, so that the customer installs it, clicks one button and starts using it?

That was the experience I wanted:

```text
Customer installs package
        ↓
Opens Agent Installer
        ↓
Reviews configuration
        ↓
Clicks Provision Agent
        ↓
Agent is ready
```

I built a proof of concept around that idea using a namespaced package called `PK4 Agent Installer POC`, with the namespace `pk4_agentforce`.

The stable package layer contained a global invocable Apex action, an Apex test and a permission set. The business capability packaged successfully. But installing those components did not automatically produce a configured, compiled and published customer agent.

That is where the interesting part began.

## Discovery 1: package installation is not agent publication

![](https://cdn.hashnode.com/uploads/covers/6a85cf8800a9107ef5771575/f592d972-9091-4354-b40c-d3d18c40f211.svg align="center")

The managed package keeps the reusable business logic. The customer org handles the agent-specific setup, instructions, and configuration.

This gives us a clean split: the package keeps the core capability, while each customer can have its own agent instructions, permissions, and configuration.

### What I actually validated

I kept the business action simple so I could isolate and test the packaging boundary.

```apex
global with sharing class PK4ProjectHealthAction {
    global class Request {
        @InvocableVariable(required=true)
        global String projectName;
    }

    global class Result {
        @InvocableVariable global String projectName;
        @InvocableVariable global String healthStatus;
        @InvocableVariable global String summary;
    }

    @InvocableMethod(label='PK4 Check Project Health')
    global static List<Result> checkHealth(List<Request> requests) {
        List<Result> results = new List<Result>();

        for (Request request : requests) {
            Result result = new Result();
            result.projectName = request.projectName;
            result.healthStatus = 'GREEN';
            result.summary = request.projectName
                + ' is healthy. Executed through the packaged action.';
            results.add(result);
        }

        return results;
    }
}
```

After installing the package, the subscriber-side Agent Script can reference the packaged capability through its namespace:

```yaml
actions:
  get_project_health:
    label: "PK4 Check Project Health"
    description: "Returns project health for a named project."
    target: "apex://pk4_agentforce__PK4ProjectHealthAction"
```

The namespace creates a clean ownership boundary. The package owns the business implementation; the subscriber agent simply references it.

| Experiment | Result |
| --- | --- |
| Create a namespaced 2GP package | Validated |
| Package an invocable Apex action | Validated |
| Package Apex permission access | Validated |
| Reference the packaged action from Agent Script | Validated in the POC |
| Start provisioning from an LWC | Validated as the administrator experience |
| Clean-org upgrades, rollback and every failure mode | Production validation backlog |

The POC validated the package/action boundary. The upgrade, retry, and rollback model below is the production architecture I derived from that experiment; those scenarios still require full validation.

## Discovery 2: the LWC should be the control plane

My next thought was: perhaps the Agent Installer LWC can create everything.

That also needed refinement.

The LWC should handle the admin experience: review the setup, choose the user the agent will run as, check prerequisites, start the process, and show progress. The actual deployment should happen in the background.

The better separation is:

```text
Administrator
      ↓
Agent Installer LWC          captures intent and shows status
      ↓
Apex orchestrator            owns workflow and subscriber setup
      ↓
Publishing implementation    compiles, publishes, polls and retries
      ↓
Agentforce
```

The LWC is the control plane: it starts provisioning and shows progress. Asynchronous orchestration executes the lifecycle.

> **Architect's takeaway:** the UI captures administrator intent; orchestration owns execution.

## Discovery 3: publishing is more than inserting metadata

Salesforce represents an editable Agent Script blueprint through the `AiAuthoringBundle` metadata type. The bundle includes the `.agent` script and its metadata definition.

Publishing that bundle is not equivalent to inserting a record. The documented Agentforce DX workflow validates and compiles Agent Script, creates or updates related agent metadata and deploys the authoring bundle.

The lifecycle is therefore closer to:

```text
Agent Script → validate → compile → publish → test → activate
```

So the agent setup process has to handle this full publishing lifecycle safely.

Salesforce documents the authoring-bundle model in [Agent Metadata](https://developer.salesforce.com/docs/ai/agentforce/guide/agent-dx-metadata.html) and the publication command in the [`sf agent publish authoring-bundle` reference](https://developer.salesforce.com/docs/platform/salesforce-cli-reference/guide/cli_reference_agent_publish_authoring-bundle.html).

## Two production directions emerged

Once I separated packaging from publishing, I saw two possible architectures.

### Architecture A: hybrid provisioning

In the hybrid approach, Salesforce handles the customer setup experience and the initial checks. A small external service handles the longer-running work such as compiling, publishing, checking status, and retrying failures.

```text
Subscriber administrator
          ↓
Agent Installer LWC
          ↓
Managed Apex orchestrator
  • preflight
  • runtime user
  • permissions
  • configuration
  • rendered template
  • provisioning job
          ↓ authenticated request
Restricted publishing service
  • validate tenant and package
  • compile and publish
  • poll and retry
  • return structured result
          ↓
Published subscriber agent
```

The external service handles long-running compilation, deployment polling, retries, and centralized monitoring. Because it accesses subscriber orgs, it also becomes part of the security boundary.

Use explicit, revocable authorization. Validate the subscriber and installed package. Accept only approved templates, and never log usernames, passwords, or access tokens.

The ideal request is logical:

```text
Provision template ProjectAgent
Version 1.3
For subscriber org X
Using configuration hash Y
```

It should never mean: “execute this arbitrary payload.”

### Architecture B: Salesforce-only provisioning

The alternative keeps the execution inside the subscriber org:

```text
Agent Installer LWC
        ↓
Managed Apex orchestrator
        ↓
Queueable Apex
        ↓
Named Credential
        ↓
Supported Salesforce API
        ↓
Poll, publish, assign and activate
```

This keeps customer configuration inside Salesforce and removes the need for an ISV-hosted publishing service.

But “Salesforce-only” does not mean “no integration.” Apex cannot execute Salesforce CLI commands. The design still needs a documented, authenticated API that provides the required publication lifecycle. A basic metadata deployment should not be assumed to perform all the same steps as the documented Agentforce publishing flow.

I would not consider the Salesforce-only design proven until it completes the full lifecycle in a clean subscriber org. Salesforce's current [Named Credentials model](https://developer.salesforce.com/docs/platform/named-credentials/guide/get-started.html) is the appropriate starting point for authenticated Apex callouts.

| Capability | Hybrid publisher | Salesforce-only |
| --- | --- | --- |
| One-click administrator experience | Yes | Potentially |
| External infrastructure | Required | Not required |
| Direct use of documented CLI publication workflow | Yes | No |
| Apex limit exposure | Lower | Higher |
| Centralized operations and retry | Strong | Distributed across orgs |
| Customer configuration remains entirely in-org | Only if the request is minimized | Yes |
| Current recommendation | Validate first | Validate API parity first |

## Agent setup is really a step-by-step state machine

![](https://cdn.hashnode.com/uploads/covers/6a85cf8800a9107ef5771575/b5d1a2e3-0bfd-42c5-acb1-01d9e4d10c7c.svg align="center")

Agent publication should not depend on an open browser request. The system needs to remember which step it is currently on, even if the page is refreshed or something fails.

Each stage should persist its status, a safe diagnostic, whether the failure is retryable, and the required recovery action. The LWC can then refresh without losing the operation, and a second click can resume an existing job instead of creating another agent.

The setup process also needs duplicate protection, often called **idempotency**.

```text
idempotency key =
subscriberOrgId + agentApiName + templateVersion + configurationHash
```

Before starting a new setup, the system checks that key to see whether the same request is already running or has already finished:Running: resume or return the current job.

*   Completed: return the existing result.
    
*   Failed: apply the retry policy.
    
*   Missing: create a new job.
    

Without idempotency, a browser refresh, Queueable retry, or lost response can create duplicate agents or versions.

## Then I found the harder problem: upgrades

Getting version 1 installed is not the real test of an ISV architecture. Upgrading it safely is.

![](https://cdn.hashnode.com/uploads/covers/6a85cf8800a9107ef5771575/815ab048-641f-4d43-9dfb-48bdf4ff1413.svg align="center")

Customers may customize the agent after installation. A later ISV upgrade must preserve those changes instead of overwriting them.

A safer model tracks three layers independently:

```text
ISV base template
        +
subscriber configuration
        +
protected customer customization
        =
proposed agent version
```

The setup and upgrade process should track the template version, package version, customer configuration, agent/version ID, rendered-script hash, publication result, and rollback target.

An upgrade can then:

1.  Detect the installed package and agent template versions.
    
2.  Identify subscriber-owned changes.
    
3.  Produce a new draft rather than overwrite the active version.
    
4.  Validate namespaces and action signatures.
    
5.  Test the proposed version.
    
6.  Require administrator review when changes are material.
    
7.  Activate only after validation.
    
8.  Preserve the prior version as a rollback target.
    

> **Architect's takeaway:** package upgrades and agent upgrades are related, but they are not the same lifecycle.

## What I would validate before calling it production-ready

Architecture diagrams are helpful. Clean-org failure testing is better.

The production validation suite should cover:

*   Clean package installation and Agent Installer initialization.
    
*   Agentforce feature, license and permission checks.
    
*   Namespaced action resolution.
    
*   Agent Script compilation and publication.
    
*   Correct runtime-user assignment.
    
*   Duplicate clicks and browser refreshes.
    
*   Expired authorization and deployment timeouts.
    
*   Invalid action references and invalid Agent Script.
    
*   Package upgrades and changed action signatures.
    
*   Customer-edited agents and protected configuration.
    
*   Failed upgrades and rollback.
    
*   Package uninstall while provisioned agent metadata remains.
    

This is where a proof of concept becomes an ISV product.

## The architecture I would validate first

Based on what I learned, I would validate the hybrid model first. I would keep the publishing implementation behind an abstraction such as:

```apex
public interface AgentPublisher {
    PublishResponse publish(AgentProvisioningJob job);
    JobStatus pollStatus(String externalJobId);
}
```

With implementations such as:

```text
AgentPublisher
  ├── HybridServicePublisher
  └── SalesforceNativePublisher
```

The LWC, setup flow, templates, customer configuration, and upgrade logic should not depend on how the agent is published.

If Salesforce later provides a package-safe API that supports the full publishing lifecycle, only the publishing layer needs to change.

## The bigger idea I took away

I started this experiment by asking:

> How can I package an Agentforce agent?

I ended it with a better question:

> How should an ISV manage the complete lifecycle of an agent across customer organizations?

The product is not simply an agent inside a package. The lifecycle itself becomes part of the product:

```text
Install capabilities
        ↓
Validate subscriber
        ↓
Provision and publish
        ↓
Test and activate
        ↓
Observe and upgrade
        ↓
Preserve customer intent
        ↓
Roll back safely
```

The managed package supplies the reusable building blocks. The setup process turns them into a customer-specific agent. Later upgrades can then add ISV improvements without losing what the customer configured.

That is the architecture I believe can turn Agentforce distribution from a manual implementation exercise into a repeatable ISV product capability.

## If you are an ISV experimenting with this

You do not need to build the complete provisioning platform on day one. Start by validating the package-to-agent boundary end to end:

1.  **Package one global invocable Apex action.** Keep the business logic simple so you can focus on validating the packaging and Agentforce integration boundary.
    
2.  **Install the package in a clean subscriber org.** Confirm that the packaged action and required permissions are available through the managed namespace.
    
3.  **Create the subscriber-side Agent Script and bind it to the packaged action.** Define a simple capability in Agent Script, then reference the action installed in step 2 through the managed namespace.
    
    ```yaml
    target: "apex://pk4_agentforce__PK4ProjectHealthAction"
    ```
    
4.  **Publish the Agent Script as an authoring bundle.** This creates the subscriber-side agent definition while keeping the business capability in the managed package.
    
5.  **Configure the runtime user and assign the required permissions.** The runtime user must be able to execute the packaged action that the Agent Script references.
    
6.  **Test the complete flow through the agent.** Verify the full chain:
    
    **Agent → Agent Script → namespaced packaged action → response**
    
7.  **Only after that works, automate the lifecycle.** Once the package-to-agent boundary is proven, add the installer LWC, orchestration, publishing abstraction, idempotency, upgrade handling, and rollback.
    

The important part is not completing a list of separate steps. It is proving one connected flow:

**Package capability → reference it from Agent Script → publish the agent → grant runtime access → invoke the packaged capability successfully**

That sequence is what made the architecture click for me.

Sometimes the most useful discovery is not finding the API you expected. It is realizing that you were solving the wrong boundary.

* * *

*How are you approaching agent distribution, subscriber-specific configuration, upgrades and rollback for ISV-built Agentforce products?*
