Skip to main content
Picture a sales team in Bengaluru selling annual software plans, as an example. Their pipeline lives in HubSpot. An agent reads the call notes after each meeting and keeps the CRM tidy: this deal moved to “contract sent”, that one’s amount went from ₹4,80,000 to ₹5,20,000 after the customer added seats. It sounds harmless. It is not. The pipeline drives the forecast, the forecast drives hiring and targets, and a deal marked “closed won” can trigger commissions and invoices. An agent that misreads a note, or is fed a note written to fool it, can quietly move a lost deal back to open or inflate an amount the week before the quarter closes.

The problem: a CRM token is too much power

The usual build hands the agent a HubSpot private app token. That token can update any deal, any property, in any direction. Whatever guardrails sit in the prompt, the token itself does not know the difference between “move forward one stage” and “rewrite the pipeline”.

The idea: narrow the action, check the real deal, ask a person

Three things make a CRM write safe enough to hand to an agent:
  1. A narrow action. Not “update HubSpot”, but “change this deal’s stage, and maybe its amount”.
  2. The real state, not the agent’s story. If the agent says the deal is at “qualified to buy”, ask HubSpot.
  3. A person for every write. Someone who can be named has signed off on this deal being changed.

How Parmana does it

The HubSpot connector has two actions: hubspot:deal-fetch to read a deal and hubspot:deal-update to change it. The update can touch exactly two properties, dealstage and amount, in one call. A request naming any other property is refused before any network call, not silently trimmed. The update runs under the policy hubspot-deal-update 1.1.0:
  • Every update needs a signed approval for that deal, whatever the amount. Under the older 1.0.0, small updates ran with no person; since 2026-09-30 none do.
  • Stages only move forward through a fixed order, from “appointment scheduled” to “closed won”, with one exception: “closed lost” is allowed from any stage that is not already closed. Moving backward, out of a closed stage, or to a stage the order does not know is refused, even with an approval.
  • The agent’s facts are checked against HubSpot. Before the policy’s decision is trusted, a verifier fetches the real deal and re-derives the current stage, whether the move is allowed, and how much the amount changes. If the agent’s declared facts do not match, the update is refused. If HubSpot cannot be reached, it is refused too.
  • The proposed values are bound. The stage and amount the agent declares must equal the stage and amount in the request, so it cannot get approval for one change and send another.
The connector holds the token. The agent never sees it, and the token’s fingerprint, never the token, is what appears in the record. On every refusal the tests show zero calls to HubSpot. This is the one built-in connector where Parmana reads the business system itself before deciding. For refunds, eligibility is still the agent’s word. For deals, the stage and amount facts come from HubSpot.

What was proven, and where

The connector is tested against a mock HubSpot server in every test run, through the real POST /execute route. In an earlier session it was also run live against a real HubSpot developer test account, three of three passing: a read of a deal that does not exist reached HubSpot and came back with a real error; a refused update made no call; and a real test deal’s amount was read, nudged by 1, confirmed changed by an independent read, then put back to its exact original value. That live run used a locally started server and a test account, not Parmana’s production deployment and not a company’s real pipeline. It ran before every update needed a signed approval, and before the live suite was rewritten to go through the published SDK. The rewritten suite has not been run live since.

What it does not do

  • The approval covers the deal, not the new values. A person approves changing this deal; the approval does not fix which stage or what amount. The stage rules and the HubSpot check still apply, but within them the approver is trusting the agent’s numbers for that one use.
  • Only deals, only stage and amount. No contacts, companies, deletes, other properties or webhooks.
  • One stage order for everyone. Per-pipeline stage orders are not wired up.
  • No real company pipeline is connected. The only live run was a test account.
  • Reads need approval too. Even fetching a deal needs a signed approval for that deal, which makes reading slower than most teams expect. That is deliberate, and its own essay.
  • One person approves. In Parmana’s own production one approver is trusted, and I hold that key.
  • It does not stop a direct call. An agent that keeps its own HubSpot token can call HubSpot without Parmana.

The takeaway

A CRM is a record of what the business believes about its customers. Letting an agent write to it is reasonable when the action is narrow, the facts come from the CRM rather than the agent, and a person signs each change. The part still missing is the one that matters most to a buyer: a run against a real team’s pipeline. Read more: HubSpot, Human approval, Credential isolation.