Security & Trust

StackJack was built security-first by engineers who’ve shipped SOC 2 Type II audited products on the same stack. Here’s exactly how we protect your data, credentials, and access.

Zero Data Storage Azure Key Vault Fail-Closed Auth Encrypted in Transit
stackjack-security

Security at a Glance

The essential security facts about StackJack — in 30 seconds.

Zero Data Storage

StackJack never stores, caches, or logs your PSA/RMM data. We’re a pass-through gateway — your data flows directly between your AI agent and your connector’s API.

Credentials in Azure Key Vault

Your connector API secrets are stored exclusively in Azure Key Vault — a FIPS 140-2 Level 2 validated HSM-backed secret store. Our database holds only a reference, never the actual secret.

Fail-Closed Authentication

Every request is authenticated and authorized through a multi-layer security pipeline. If any validation step fails, the request is denied. No exceptions, no fallbacks.

Tenant Isolation

Your data, credentials, rate limits, and access controls are completely isolated from every other tenant. There are no cross-tenant queries anywhere in the system.

Encrypted Everywhere

All traffic flows over HTTPS with TLS 1.2+. Database connections are encrypted. Redis connections are SSL-only. There is no unencrypted path through our infrastructure.

Granular Access Controls

Restrict which tools each AI agent or team member can use. Set per-client and per-user tool allowlists. If a tool isn’t on the list, it can’t be called — fail-closed.

The StackJack Security Model

A detailed look at how every layer of StackJack is designed to protect your data and access.

Pass-Through Gateway Architecture

StackJack is a stateless proxy. Your connector data flows through, never stops.

How It Works

Your AI agent sends a tool call to StackJack. We authenticate the request, resolve your tenant, and forward the API call to your connector — HaloPSA, Autotask, ConnectWise, NinjaRMM, or CIPP. The connector’s response is returned directly to your AI agent. StackJack is a stateless proxy — nothing is stored between requests.

What We Retain

Only audit metadata: which tool was called, whether it succeeded or failed, and how long it took. This powers your usage dashboard and audit trail. We never retain request parameters or response content.

What We Don’t Retain

Tickets, clients, devices, contacts, invoices, assets — none of it. No caching, no indexing, no logging of your connector data. Your operational data never touches our database.

Credential Management

Every secret is encrypted, hashed, or stored in a hardware security module. Zero plaintext, anywhere.

Azure Key Vault

All connector API secrets — client secrets, refresh tokens, API keys — are stored in Azure Key Vault, a FIPS 140-2 Level 2 validated, HSM-backed secret store. Our database stores only a reference to the Key Vault secret, never the credentials themselves. Even with full database access, an attacker would find zero usable credentials.

MCP Client Secrets

When you create an MCP client, a cryptographically random 256-bit secret is generated and shown to you exactly once. We store only an irreversible BCrypt hash. We cannot recover your secret — if it’s lost, you rotate it to generate a new one.

Zero Plaintext Policy

No plaintext secrets exist in the database, cache, or logs. Connector credentials live in Key Vault. Client secrets are BCrypt hashed. OAuth signing keys are in Key Vault. This is enforced architecturally, not by policy — there is no code path that could store a plaintext secret.

Authentication Pipeline

Three sequential security layers. All must pass. Any failure means immediate denial.

Multi-Layer Pipeline

Every MCP request passes through three sequential security layers. Layer 1: Tenant Resolution — authenticates via JWT Bearer token or HTTP Basic credentials and resolves your tenant identity. Layer 2: Authorization — verifies your subscription is active and connector credentials can be loaded. Layer 3: Rate Limiting — enforces burst and monthly usage limits. All three must pass. Any failure returns an immediate denial.

OAuth 2.0 with PKCE

PKCE (Proof Key for Code Exchange) is required on all authorization code flows — no exceptions. Access tokens are RSA-signed JWTs with short expiry. Refresh tokens are single-use and rotated on every use — a stolen refresh token gets exactly one use before it’s invalid. Authorization codes are atomic single-use and expire in minutes.

Fail-Closed Design

Here’s what gets denied: JWT invalid or expired. Tenant not found. Subscription inactive. Credentials can’t be loaded from Key Vault. Tool not in the client’s allowlist. Rate limit exceeded. Non-member attempting access. There is no fallback mode, no degraded access, no “let it through anyway.”

Tenant Isolation

Your data is architecturally unreachable by any other tenant.

Database Isolation

Every database query includes your tenant ID in the WHERE clause. There are no admin endpoints that query across tenants. No reports aggregate cross-tenant data. Cross-tenant data access is architecturally unreachable — it’s not a policy, it’s a code-level impossibility.

Credential Isolation

Each tenant’s connector secrets are stored as separate entries in Azure Key Vault, scoped by tenant identity. Credential lookup is scoped by the authenticated tenant identity established in Layer 1 — a tenant can only ever access their own secrets.

Cache & Rate Limit Isolation

All cached data is keyed by tenant ID. Rate limits are tracked independently per tenant per connector. One tenant hitting their rate limit has zero effect on any other tenant — your limits are yours alone.

Rate Limiting & Abuse Prevention

Multiple layers of protection for your connector APIs and every other tenant on the platform.

Multi-Layer Rate Limiting

Rate limiting operates at three independent layers: per-tenant burst limits (per-minute), per-connector monthly usage caps (Free: 100, Pro: 5,000, Business: 50,000), and upstream API protection. Each layer enforces independently — passing one doesn’t exempt you from the others.

Upstream API Protection

StackJack tracks request rates per connector and stays within each vendor’s API thresholds. If an upstream API returns a rate limit response, StackJack automatically backs off. This prevents your connector account from being throttled or suspended by the vendor.

Structured Error Responses

When a rate limit is hit, AI agents receive a structured JSON response with the exact limit, current usage, and a Retry-After interval. These responses are designed for machine consumption — your AI agent knows exactly when it can try again.

Transport Security

Every connection is encrypted. There is no unencrypted path through StackJack.

HTTPS Everywhere

All production traffic flows over HTTPS with TLS termination at the Azure edge. The database requires encrypted connections with TLS 1.2+. Redis is SSL-only — the non-SSL port is disabled. Key Vault access uses HTTPS with managed identity authentication. There are zero unencrypted paths.

Streamable HTTP Transport

StackJack uses pure HTTP request/response over HTTPS. No persistent connections, no WebSocket upgrade paths, no long-lived sessions. Every request is independently authenticated — there is no session state that could be hijacked.

Resilience Patterns

All upstream API calls include automatic retry with exponential backoff, circuit breakers, and configurable timeouts. When a connector API is having issues, StackJack degrades gracefully with structured error responses rather than hanging or returning cryptic failures.

MCP Security: Myths vs. Reality

We keep seeing the same claims about MCP security. Here’s what’s actually true — in enough detail that you don’t need to ask a follow-up.

“MCP is inherently insecure”

MCP is a protocol, not a product — the same way HTTP is a protocol. Saying “MCP is insecure” is like saying “HTTP is insecure.” It depends entirely on how it’s implemented.

Most MCP criticism is aimed at the local stdio transport — where an MCP server runs on your machine with credentials stored in plaintext JSON config files, no authentication, and any local process able to connect. That is a reasonable concern for that specific configuration.

StackJack is a completely different model. We implement remote authenticated MCP via Streamable HTTP over HTTPS. Every request passes through multi-layer authentication, credentials are in Azure Key Vault (not JSON files), access is fail-closed, and all traffic is encrypted.

Think of the difference like SQLite on a desktop versus a production database with encryption at rest, RBAC, and TLS. Same underlying concept — SQL — but a completely different security posture. That’s the difference between local stdio MCP and StackJack.

“There’s no authentication in MCP”

For local stdio MCP, this is true — the protocol itself doesn’t include built-in authentication. But that’s the stdio transport, not MCP as a whole.

StackJack uses the Streamable HTTP transport with full OAuth 2.0 and PKCE. We also support HTTP Basic authentication with BCrypt-hashed secrets. Every single request is cryptographically verified before it touches any connector API.

Our OAuth implementation includes RSA-256 signed JWT access tokens with short expiry, single-use refresh tokens that are rotated on every use, and PKCE required on all authorization code flows. We also support Dynamic Client Registration with rate limiting to prevent automated abuse.

Even with a valid token, non-members are denied access — you must be the tenant owner or an active member to use StackJack tools. Token validity alone is not sufficient.

“MCP servers can access all your data”

StackJack enforces per-client and per-user tool allowlists. As an admin, you configure exactly which tools each MCP client or team member can access. If you want an AI agent to only search tickets and look up clients, that’s all it gets.

When an allowlist is configured, StackJack operates fail-closed: only tools explicitly on the list can be called. Everything else is denied with a structured error response. There’s no way to bypass this — the check happens in the tool execution pipeline before any API call is forwarded.

Plan-based gating adds another layer. Certain advanced tools require higher subscription tiers. Even if a tool is in the allowlist, it won’t execute if the subscription plan doesn’t meet the tool’s minimum requirement.

Bulk operations are capped per call. Input parameters are validated. Page sizes are clamped to safe maximums. StackJack doesn’t just control which tools you can use — it controls how they’re used.

“An AI could delete everything in my PSA”

The admin controls tool exposure — not the AI. You decide which tools to make available through per-client and per-user allowlists. If you don’t expose delete tools, the AI can’t call them. It’s that simple.

The majority of StackJack tools are read-only — search, list, get operations. Write and destructive operations exist, but they require explicit enablement through your tool configuration. No destructive tool is available by default unless you choose to include it.

Bulk operations are capped per call with ID format validation. Input validation catches malformed parameters before they reach the connector API. All calls are logged with a full audit trail — tenant, client, user, tool name, success/failure, and duration.

An AI agent cannot force its way past access controls. It receives exactly the tools you’ve allowed, operates within the limits you’ve set, and every action is logged. The AI can only do what you’ve explicitly permitted.

“A third party proxying my API calls can see all my data”

StackJack is a stateless pass-through gateway. Your connector data flows through StackJack over encrypted channels, but it is never stored, cached, indexed, or logged.

The only data we retain from tool calls is audit metadata — which tool was called, whether it succeeded, and how long it took. We do not log request parameters or response content. No employee can pull up a query that shows your tickets, clients, devices, or invoices — that data doesn’t exist on our infrastructure.

Infrastructure access is secured with managed identity authentication through Azure — no stored connection passwords, no credential files on servers. The application authenticates to Azure services cryptographically through the platform itself.

Think of it like a TLS-terminating load balancer. Data passes through, gets routed to the right place, but nothing persists. The difference is that StackJack also authenticates, authorizes, and rate-limits every request that passes through.

“What if the MCP server gets compromised?”

StackJack is built with defense in depth — every layer is designed to limit the blast radius of a compromise at any other layer.

Connector credentials are in Azure Key Vault (HSM-backed), not in the database. Even with full database access, an attacker gets zero usable connector credentials — just references to Key Vault entries they can’t access. MCP client secrets are BCrypt hashed, which is irreversible — they can’t be used even if extracted.

Access tokens have short expiry. Refresh tokens are single-use and rotate on every use. Tenant isolation means one tenant’s compromise doesn’t expose others. Managed identity means there are no stored connection passwords that could be extracted from the application.

Key Vault has soft delete and purge protection enabled — even accidental or malicious deletion is recoverable. Credential rotation and client revocation are instant through the Portal.

The blast radius is minimized at every layer: secrets can’t be extracted from the DB, tokens expire quickly, refresh tokens are one-time use, tenants are isolated, and Key Vault protects against deletion. There is no single point of compromise that exposes everything.

“I’m concerned about security”

Good. You should be. Any MSP evaluating a tool that touches their PSA or RMM APIs should be asking hard questions about security. That’s exactly the right instinct.

StackJack was built security-first by engineers who’ve shipped SOC 2 Type II audited products on the same .NET stack, the same Azure infrastructure, and the same security patterns. We default to deny, encrypt by default, and isolate by default — not because a compliance checklist told us to, but because that’s how we build software.

This page exists to show you the architecture, not to ask you to trust us. You can see exactly how credentials are managed, how the authentication pipeline works, how tenant isolation is enforced, and what happens when things go wrong.

If this page doesn’t cover something you need to know, ask us directly. We’d rather answer a hard question than leave you guessing. Reach out at ceej@stackjack.io.

stackjack-defense

Compliance & Infrastructure

Where your data lives and the standards we build to.

Azure Infrastructure

All services run on Microsoft Azure. Azure SQL with TDE encryption at rest and encrypted connections. Azure Key Vault with RBAC, soft delete, and purge protection. Azure Redis Cache SSL-only with TLS 1.2+. Azure Container Apps with managed identity, HTTPS-only ingress, and auto-scaling.

SOC 2 Type II Roadmap

SOC 2 Type II certification is on our compliance roadmap. StackJack was built by engineers whose other products have successfully completed SOC 2 Type II audits — built on the same .NET stack, the same Azure infrastructure, and the same security patterns. We’re confident in the outcome.

Audit Logging

Every tool call is logged with tenant ID, client ID, authenticated user ID, connector type, tool name, success/failure, and duration. This powers your usage dashboard and audit trail. Request parameters and response content are never logged.

Data Residency

All infrastructure runs on Microsoft Azure. Customer connector data never persists on StackJack infrastructure. No data is replicated to third-party services. Account data, secrets, and audit logs are all within Azure.

Frequently Asked Questions

Comprehensive answers to every security question we've been asked. If yours isn't here, contact us.

Data & Privacy

Does StackJack store my PSA/RMM data?

No. StackJack is a pass-through gateway. When an AI agent calls a tool — for example, searching tickets in HaloPSA or listing devices in NinjaRMM — StackJack forwards the API call to your connector’s API using your credentials, and the response flows directly back to the AI agent. Your operational data transits through StackJack’s memory during request processing and is immediately discarded.

Your tickets, clients, devices, contacts, invoices, assets, and every other piece of PSA/RMM data are never stored, cached, indexed, or logged by StackJack. There is no database table, no cache layer, no log file, and no search index that contains your connector data. It does not exist on our infrastructure beyond the moment of transit.

The only metadata StackJack retains from tool calls is the audit record: the tool name, whether it succeeded or failed, and how long it took. We never log the request parameters you sent or the response content your connector returned. This means there is zero operational data to breach, leak, or subpoena — because we never had it in the first place.

What data does StackJack actually collect and store?

StackJack stores only what is needed to operate the service. Here is the complete list: tenant name and email (account identification), Zitadel user IDs (identity provider linkage), Stripe customer ID (billing linkage), team member emails and display names (team management), connector instance URLs (API endpoint routing), usage logs (tool name, duration, success/fail, and truncated error messages on failure), and support ticket content and attachments (customer support).

Connector credentials (API keys, client secrets, refresh tokens) are stored exclusively in Azure Key Vault — the database holds only a reference name pointing to the Key Vault entry. MCP client secrets are stored only as irreversible BCrypt hashes. We cannot recover or display the original secret.

What we do not store: your PSA/RMM data (tickets, clients, devices, contacts, invoices, assets), AI conversation history or prompts, tool call parameters, API request bodies, API response bodies, or any content that flows between your AI agent and your connector. None of that data exists anywhere on our infrastructure.

Do you log API request or response content?

No. StackJack’s usage logs contain only operational metadata: tenant ID, MCP client ID, authenticated user ID, connector type, tool name, duration in milliseconds, success or failure status, and a truncated error message (on failure only, capped at 2,000 characters). That is the complete set of fields. Request parameters and response bodies are never recorded.

This means if your AI agent calls halo_search_tickets with a search query and gets back a list of tickets, our log records only that halo_search_tickets was called, that it succeeded, and how long it took. The search query itself, the ticket data returned, and every other detail of the request and response are discarded immediately after transit.

Our error tracking system (Sentry) is configured with SendDefaultPii disabled, which means personally identifiable information is not captured in error reports or breadcrumbs. Sentry receives application-level exceptions with stack traces and tenant context for debugging, but never your connector data.

Do you log tool call parameters?

No. We log only the tool name, never the parameters passed to it. If you call halo_search_tickets with a search query containing a client name, we log that halo_search_tickets was called. We do not log the search query. If you call ninja_get_device with a device ID, we log that ninja_get_device was called. We do not log the device ID.

This is a deliberate architectural decision, not an oversight. Tool parameters often contain sensitive information — client names, ticket subjects, device identifiers, contact details. By never logging parameters, we ensure that no customer operational data exists in our logs under any circumstances, regardless of which tools are called or what data flows through them.

The same applies to response content. The data your connector returns flows through StackJack’s memory during the request and is returned to your AI agent. It is never written to any persistent storage, cache, or log.

Can StackJack employees see my tickets, clients, or devices?

No. Your connector data — tickets, clients, devices, contacts, invoices, assets — never persists anywhere on StackJack’s infrastructure. It flows through application memory during a request and is discarded immediately. There is no database table, no cache entry, no log file, and no admin interface that contains your PSA/RMM data.

A StackJack employee with full database access would find: tenant names and emails, connector instance URLs, subscription details, and usage logs showing which tools were called. They would find zero customer operational data — no ticket subjects, no client names, no device details, no contact information. The data simply does not exist on our systems.

Connector credentials are stored in Azure Key Vault, which is accessed only by the application’s managed identity — a cryptographic identity assigned by Azure. No human has the credentials to retrieve secrets from Key Vault via a config file, environment variable, or password manager. Even if an employee accessed the database directly, they would find only reference names pointing to Key Vault entries, not the actual credentials.

Do you sell, share, or monetize my data?

No. StackJack does not sell, share, or monetize your data in any way. We do not use third-party analytics services on customer operational data. We do not share data with data brokers. We do not serve advertising. We do not share data with partners, affiliates, or any other third party.

StackJack’s revenue comes exclusively from subscription fees — the plans you see on our pricing page. Your data is not our product. You are not the product. The service we sell is secure MCP connectivity between your AI tools and your MSP platforms, and that is the only way we generate revenue.

Furthermore, because StackJack operates as a pass-through gateway, we don’t even have access to your operational data in a form that could be monetized. Your tickets, clients, devices, and contacts flow through our application memory and are immediately discarded. There is nothing to sell even if we wanted to — which we do not.

Do you use my data to train AI models?

No. StackJack does not train AI models and does not provide data to AI providers for training. This is a common concern, so let us be precise about what StackJack sees and does not see in the AI workflow.

Your AI conversations happen between your AI client (Claude, Copilot, Cursor) and the AI provider (Anthropic, OpenAI, etc.). StackJack is not part of that conversation. When your AI agent decides it needs to use a tool — like searching tickets or listing devices — it sends a tool call request to StackJack. We see only the tool name and parameters for that single request. We do not see the conversation that led to the tool call, the AI’s reasoning, your prompts, or any other context.

Of the tool call data we do see, we log only the tool name (not the parameters, not the response). We do not store, aggregate, or analyze tool call content for any purpose beyond request processing. We do not train models. We do not fine-tune models. We do not contribute data to datasets. Your operational data is processed in memory and discarded.

What happens to my data if I cancel my subscription?

When you cancel a subscription, your account data is retained until you explicitly request deletion. This allows you to reactivate your subscription later without re-configuring everything. Your connector credentials can be removed immediately through the Portal if you prefer not to keep them on file.

There is no connector data to worry about, because StackJack never stored your operational data in the first place. Your tickets, clients, devices, and other PSA/RMM data never existed on our infrastructure — it flowed through in real time and was discarded. Canceling does not trigger any data deletion because there is nothing to delete on that front.

Usage logs (tool name, success/fail, duration) are retained per standard retention policy. If you want to fully remove your presence from StackJack, you can request complete account deletion at any time by contacting support or initiating it through the Portal. This cascade-deletes all database records, purges Key Vault secrets, and lets Redis cache entries expire naturally within minutes.

Can I delete my account and all associated data?

Yes. You can request full account deletion at any time by contacting support or initiating the process through the StackJack Portal. When a tenant is deleted, the process is thorough and cascading.

Database records: All data associated with your tenant is cascade-deleted — this includes your account information, connector configurations, subscription records, MCP client entries, team member records, usage logs, and any pending invitations. The tenant is the root entity, and all child records are removed when it is deleted.

Azure Key Vault: All secrets associated with your tenant (connector credentials, per-user credentials) are purged from Key Vault. Redis cache: All cache entries keyed to your tenant ID expire naturally within minutes — credential caches, rate limit counters, and usage counters all have explicit time-to-live values and will not persist beyond their configured windows. After deletion, there is no recoverable trace of your tenant on our infrastructure.

How long do you retain data?

Usage logs are retained in the database with indexed timestamps for efficient querying and future retention policy enforcement. These logs contain only tool name, success/fail, duration, and error messages — never request parameters or response content. They power your usage dashboard and audit trail in the Portal.

Redis cache entries have explicit time-to-live (TTL) values — nothing persists indefinitely. Cached credentials expire within minutes. OAuth tokens, authorization codes, and session state all have defined lifetimes ranging from minutes to days depending on their purpose. Rate limit counters reset on their configured windows. When an entry’s TTL elapses, Redis automatically removes it.

Connector data is never retained at all — it flows through application memory during request processing and is discarded immediately. Support ticket data (messages and attachments) is retained for as long as your account exists. Account data (name, email, configuration) is retained until you request deletion. You can request full account deletion at any time, which cascade-deletes all associated records.

Do you replicate data to any third-party services?

No. All StackJack infrastructure runs on Microsoft Azure. There is no data replication to third-party analytics, logging, or monitoring services for customer operational data. Your account data, connector credentials, and usage logs all live within Azure’s infrastructure and are not exported or mirrored elsewhere.

Our error tracking system (Sentry) captures application-level exceptions with stack traces and tenant context for debugging purposes, but it is explicitly configured to never capture personally identifiable information. Sentry receives error types, stack traces, and operational metadata (which tenant was affected, which connector type) — but never your PSA/RMM data, never request parameters, and never response content.

Application Insights (Azure’s own telemetry service) collects performance metrics, distributed traces, and structured logs for infrastructure monitoring. This is an Azure-native service within the same cloud platform — not a third-party data export. No customer connector data flows to Application Insights; it receives only application performance data.

Where is my data physically stored?

All StackJack infrastructure runs on Microsoft Azure. Here is where each category of data lives: Azure SQL Server stores your account data, subscription records, team member information, and usage audit logs with Transparent Data Encryption (TDE) at rest. Azure Key Vault stores all connector credentials and OAuth signing keys in an HSM-backed, FIPS 140-2 Level 2 validated secret store. Azure Redis Cache handles caching, rate limiting, and session management with SSL-only connections and TLS 1.2 minimum.

The application itself is hosted on Azure Container Apps with managed TLS, HTTPS-only ingress, and auto-scaling. Support ticket attachments are stored in Azure Blob Storage. Container images are stored in Azure Container Registry.

No data is replicated outside of Azure. There are no third-party databases, no external logging services receiving customer data, and no cross-cloud replication. Your connector data (tickets, clients, devices) is never stored on our infrastructure at all — it passes through in memory and is discarded immediately.

Credentials & Secrets

How are my connector credentials (API keys, client secrets) stored?

Your connector credentials are stored exclusively in Azure Key Vault — Microsoft’s FIPS 140-2 Level 2 validated, HSM-backed secret management service. This is not a database field with encryption. It is a dedicated, purpose-built secret store backed by hardware security modules that have been independently certified for tamper-evidence and tamper-resistance.

The StackJack database stores only a reference name pointing to the Key Vault entry — never the actual credential. Even with full database access, an attacker would find zero usable credentials. They would see reference strings that are meaningless without access to Key Vault itself.

Key Vault access is granted only to StackJack’s managed identity — a cryptographic identity assigned by Azure to the application container. Access is controlled by Azure’s RBAC (Role-Based Access Control) system, not by stored passwords or connection strings. Key Vault also has soft delete and purge protection enabled, which means secrets cannot be permanently destroyed accidentally and are recoverable within a retention window.

To reduce the number of Key Vault calls, credentials are cached briefly in Redis. When credentials are updated or rotated, the cache is immediately evicted to ensure the fresh credential is used on the next request.

What is Azure Key Vault and why does it matter?

Azure Key Vault is Microsoft’s cloud-native secret management service, purpose-built for storing and controlling access to secrets, encryption keys, and certificates. It is the same service used by enterprises, financial institutions, and government agencies worldwide to protect their most sensitive credentials.

FIPS 140-2 Level 2 validated means the hardware backing Key Vault has been independently certified by a government-accredited lab for tamper-evidence — physical attempts to access the hardware are detectable. HSM-backed means your secrets are protected by dedicated Hardware Security Modules — specialized cryptographic processors designed to safeguard key material. RBAC authorization means access to secrets is controlled by Azure’s identity-based role system, not by shared passwords or API keys.

Key Vault also provides soft delete with purge protection, meaning secrets cannot be permanently destroyed accidentally. Deleted secrets enter a recovery window before permanent removal. This protects against both accidental deletion and malicious destruction attempts. All access to Key Vault is logged and auditable by Azure’s platform.

For StackJack, this means your connector API credentials (HaloPSA client secrets, Autotask API keys, NinjaRMM API keys, ConnectWise key pairs, CIPP client secrets) are protected by the same infrastructure that guards secrets for the world’s largest organizations — not by a database column with application-level encryption.

Can StackJack employees access my connector credentials?

No. Credentials are retrieved by the application using a managed identity — a cryptographic identity assigned by Azure to the application container. This is not a username and password stored in a config file. It is an identity that exists only within Azure’s platform and can only be used by the specific container it is assigned to.

No human has credentials to access Key Vault in a configuration file, environment variable, or password manager. Access is granted to the application identity by Azure’s RBAC system, not to human user accounts. There is no admin panel, no backdoor, and no support tool that allows a StackJack employee to retrieve your connector credentials.

Even if an employee accessed the database directly, they would find only reference names pointing to Key Vault entries — not the actual secrets. Those reference names are useless without the managed identity that Azure grants only to the running application. The separation is enforced at the infrastructure level by Microsoft’s identity platform, not by application code that could be bypassed.

How are MCP client secrets handled?

When you create an MCP client in the StackJack Portal, a cryptographically random 256-bit secret is generated using a secure random number generator and displayed to you exactly once. This is the only time the plaintext secret is visible to anyone — including you.

StackJack immediately computes an irreversible BCrypt hash of the secret and stores only the hash in the database. BCrypt is a one-way hashing algorithm specifically designed for password and secret storage. The original secret cannot be recovered, decrypted, or reverse-engineered from the hash. We cannot display it, email it to you, or look it up on your behalf.

When your AI agent authenticates with StackJack using HTTP Basic Auth, we hash the provided secret with BCrypt and compare it to the stored hash. The comparison is constant-time (built into the BCrypt library) to prevent timing attacks. If the hashes match, authentication succeeds. If they do not, the request is denied.

If you lose your MCP client secret, the only option is to rotate it — which generates a new cryptographically random secret (shown once) and immediately invalidates the old one. This is intentional security, not a limitation.

What happens if I lose my MCP client secret?

You rotate it through the StackJack Portal. There is no recovery mechanism — this is by design. StackJack stores only an irreversible BCrypt hash of your secret. We cannot recover, decrypt, or display the original. No support representative can look it up for you.

When you rotate the secret, StackJack generates a new cryptographically random 256-bit secret and displays it to you exactly once. The old BCrypt hash is replaced with a hash of the new secret. The change takes effect immediately — any AI agent configured with the old secret will stop authenticating until you update it with the new one.

This is the correct behavior. If we could recover your secret, it would mean we stored it in a reversible format — which would be a security weakness. The inability to recover lost secrets is a feature of the security model, not a limitation. We recommend storing your MCP client secrets in your organization’s password manager or secrets vault immediately after creation.

Can I rotate my credentials?

Yes. Both connector credentials and MCP client secrets can be rotated instantly through the StackJack Portal, and the change takes effect immediately.

For connector credentials (your HaloPSA, Autotask, NinjaRMM, ConnectWise, or CIPP API credentials): when you update them, the new credentials are written to Azure Key Vault, the Redis cache is immediately evicted so the old credentials are not used on subsequent requests, and the old Key Vault secret version is soft-deleted (recoverable within Azure’s retention window, then permanently removed).

For MCP client secrets (the credentials your AI agents use to authenticate with StackJack): rotation generates a new cryptographically random 256-bit secret, displays it to you once, and replaces the old BCrypt hash with a hash of the new secret. The old secret is immediately invalid. Any AI agent using the old secret will receive a 401 Unauthorized response until updated with the new one.

We recommend rotating credentials on a regular schedule and immediately after any suspected compromise. Both rotation operations can be performed in seconds through the Portal with no downtime beyond reconfiguring your AI agents or connector settings.

What’s the difference between shared and per-user credentials?

Shared credentials (available on Free and Pro plans) means one set of connector credentials per tenant per connector. All team members and MCP clients for that tenant share the same upstream API credentials. When any AI agent on your account calls HaloPSA, it uses the same API credentials. Audit logs at the connector level show all activity under one identity.

Per-user credentials means each team member authenticates with the upstream connector independently. Each person provides their own API credentials (or authenticates via OAuth), and their credentials are stored as separate Key Vault secrets scoped to their individual identity.

The practical impact is significant for teams: per-user credentials enable per-user audit trails at the connector level. When a team member performs an action through StackJack, the upstream PSA/RMM system logs it under that individual’s identity — not a shared service account. This is important for compliance, accountability, and understanding who did what. It also prevents credential sharing between team members and limits the blast radius if any individual’s credentials are compromised.

How are OAuth tokens for upstream APIs managed?

OAuth tokens for your connectors (HaloPSA, Autotask, NinjaRMM, CIPP) are cached in Redis with a TTL set conservatively below the token’s actual expiry time. This prevents StackJack from ever attempting to use an expired token. When a token approaches expiry, it is refreshed automatically before the next API call that needs it.

Token refresh is coordinated across all application replicas using distributed locks in Redis. When multiple replicas detect that a token needs refreshing simultaneously, only one replica wins the lock and performs the refresh. The other replicas wait for the winner to populate the fresh token in the cache, preventing a thundering herd of simultaneous refresh requests to the upstream API.

When a token is successfully refreshed and the upstream API issues an updated refresh token, the new refresh token is written back to Azure Key Vault and the Redis cache is evicted so the updated credentials are picked up on subsequent requests. This entire process happens transparently — your AI agents see no interruption. If a refresh fails, the error is surfaced to the AI agent as a structured error response with actionable guidance.

Are my credentials encrypted at rest and in transit?

Yes, at every layer. Encryption protects your credentials both when they are stored and when they move between systems.

In transit: All API calls — between your AI agent and StackJack, between StackJack and your connectors, and between StackJack and Azure services — use HTTPS with TLS 1.2 or higher. Azure Container Apps provides TLS termination at the edge. Redis connections are SSL-only with TLS 1.2 minimum. SQL Server connections enforce encryption with certificate validation.

At rest: Azure Key Vault uses HSM-backed encryption for all stored secrets. Azure SQL Server uses Transparent Data Encryption (TDE), which encrypts the database files at the storage layer. Azure Redis Cache encrypts data at rest within Azure’s infrastructure. MCP client secrets are stored as BCrypt hashes, which are irreversible — even stronger than encryption because there is no key that could decrypt them.

There is no point in the system where your credentials exist in plaintext outside of the application’s memory during active request processing. From the moment you enter credentials in the Portal to the moment they are used to call your connector’s API, they are protected by hardware-backed encryption and secure transport protocols.

Authentication

How does authentication work for AI agents?

Every request to StackJack’s MCP endpoint passes through a multi-layer security pipeline that must fully succeed before any tool executes. This is not a single authentication check — it is a sequential series of validations, each of which must pass.

Layer 1 — Identity: Your identity is established via one of two methods. Either a Bearer token (a JWT validated against RSA-256 signatures, with issuer, audience, and expiry checks) or HTTP Basic credentials (your MCP client’s Client ID and Secret, verified against a stored BCrypt hash). If neither method succeeds, the request is rejected immediately with a 401 response.

Layer 2 — Authorization: Your tenant is resolved from the authenticated identity. The system verifies you have at least one active connector subscription and that connector credentials were successfully loaded from Key Vault. If your subscription is expired or credentials cannot be loaded, the request is rejected with a 403 response.

Layer 3 — Rate Limiting: Per-tenant burst limits and per-connector monthly usage caps are checked against Redis counters. If either limit is exceeded, the request is rejected with a 429 response and a Retry-After header. Only after all three layers pass does the tool execute and your connector’s API get contacted.

What authentication methods do you support?

StackJack supports two authentication methods for AI agents connecting to the MCP endpoint, plus a separate method for the management Portal.

HTTP Basic Auth: Your MCP client’s Client ID and Secret, sent via the standard HTTP Authorization header. The secret is verified against a stored BCrypt hash. This is the simplest method and works with any HTTP client. It requires no token exchange flow — just include the credentials in each request.

OAuth 2.0 with PKCE: A full authorization code flow with RSA-256 signed JWT access tokens. This supports both pre-registered clients (which receive client credentials during setup) and user-delegated access through OpenID Connect (OIDC) via Zitadel. PKCE (Proof Key for Code Exchange) is required on all authorization code flows to prevent code interception attacks. This is the more sophisticated method, enabling per-user identity and token-based access control.

Portal (management UI): The Portal uses OpenID Connect (authorization code flow with PKCE) through Zitadel as the identity provider. Sessions are managed via secure, HttpOnly cookies with HTTPS-only enforcement and SameSite protections. This is a separate authentication surface from the MCP endpoint.

What is OAuth 2.0 with PKCE and why do you use it?

OAuth 2.0 is the industry standard protocol for delegated authorization — it allows an application to access resources on behalf of a user without the user sharing their password. It is the same standard used by Google, Microsoft, GitHub, and virtually every major API provider.

PKCE (Proof Key for Code Exchange, pronounced “pixie”) is an extension that adds protection against authorization code interception attacks. In the standard OAuth flow, the client receives an authorization code and exchanges it for tokens. If an attacker intercepts that code (for example, through a malicious app on the same device), they could exchange it themselves. PKCE prevents this by requiring the client to prove it initiated the original request using a cryptographic code verifier that never leaves the client.

StackJack requires PKCE on all authorization code flows using the S256 challenge method (SHA-256 hashed). We do not support the plain challenge method. This is enforced server-side — authorization requests without a valid PKCE challenge are rejected. Combined with single-use authorization codes that are redeemed atomically, this provides robust protection against the most common OAuth attack vectors.

We use OAuth 2.0 with PKCE because MCP clients like Claude Desktop support the MCP OAuth flow natively, enabling seamless authentication without manual credential configuration. It also enables per-user identity when combined with OIDC, allowing StackJack to know exactly which human is behind each tool call.

What does “fail-closed” authentication mean?

Fail-closed means that if authentication cannot be positively confirmed, the request is denied. There is no “maybe” state, no degraded mode, no “let it through and check later” fallback. The system defaults to “no” and requires positive proof before allowing access.

Concretely: if the JWT signature is invalid, the request is denied. If the JWT has expired, denied. If the tenant cannot be found, denied. If the subscription has expired, denied. If the connector credentials cannot be loaded from Key Vault, denied. If the tool is not in the client’s allowlist, denied. If the monthly usage limit has been exceeded, denied.

This is the opposite of “fail-open” systems that default to allowing access when something goes wrong. Fail-open is dangerous because any system error could inadvertently grant access. StackJack’s fail-closed design means that bugs, configuration errors, and infrastructure issues result in denied access rather than unauthorized access. We would rather have a false rejection than a false acceptance.

Every layer of the security pipeline is independently fail-closed. Even if authentication succeeds but authorization fails, the request is denied. Even if authorization succeeds but rate limiting cannot be checked, the request is denied. Each check must independently and positively pass.

What happens if an authentication attempt fails?

The request is immediately rejected with an appropriate HTTP status code. No tool call is attempted. No connector API is contacted. No data flows. The failure is fast, clean, and specific.

The status codes are: 401 Unauthorized for identity failures (invalid credentials, expired token, unknown client), 403 Forbidden for authorization failures (no active subscription, tool not allowed, missing credentials), and 429 Too Many Requests for rate limit violations (with a Retry-After header indicating when to try again).

The AI agent receives a structured error response in JSON format. This includes an error type classification (so the AI can programmatically determine what went wrong), a retryable flag (so the AI knows whether retrying is appropriate), the tool name, a human-readable message explaining the failure, and actionable guidance suggesting next steps. This is designed for AI agent consumption — the agent can make informed decisions about what to do next rather than blindly retrying.

Can someone brute-force my MCP client credentials?

Practically infeasible. MCP client secrets are 256-bit cryptographically random values generated by a secure random number generator. The search space is 2256 possible values — a number so astronomically large that exhaustive search is physically impossible with any known or foreseeable computing technology.

Even if an attacker could somehow attempt billions of guesses, each authentication attempt uses BCrypt hashing, which is deliberately computationally expensive. BCrypt is designed to be slow — each verification attempt requires significant CPU time. This makes brute-force attacks extremely resource-intensive even at scale, as each guess costs real computation rather than a simple comparison.

Beyond the cryptographic protections, StackJack enforces rate limiting at multiple layers. Per-tenant burst limits restrict how many requests can be made per minute, and all rate limiting is enforced before authentication processing completes. An attacker would be rate-limited long before they could make meaningful progress against a 256-bit key space. The combination of an astronomically large search space, computationally expensive hashing, and network-level rate limiting makes brute-force attacks against MCP client credentials a non-viable attack vector.

How do JWT access tokens work in StackJack?

JWT (JSON Web Token) access tokens are signed with RSA-256 using a private key stored in Azure Key Vault. The signing key is a 2048-bit RSA key pair loaded once at application startup and consistent across all application replicas. The public key is published via a standard JWKS (JSON Web Key Set) endpoint for token verification.

Each token contains claims identifying the tenant, MCP client, and authenticated user (when applicable). StackJack validates every aspect of the token on every request: the RSA-256 signature (proving the token was issued by StackJack and has not been tampered with), the issuer, the audience, and the expiry timestamp.

Access tokens have a short lifetime (measured in hours, not days or weeks). This limits the window during which a stolen token could be used. After expiry, the client must use a refresh token to obtain a new access token, or re-authenticate entirely. The short lifetime is a deliberate security choice — tokens are cheap to issue but expensive to steal and use if they expire quickly.

How long are access tokens valid?

Access tokens have a short lifetime measured in hours, not days or weeks. This is a deliberate security decision that balances usability with the principle of limiting exposure.

The short lifetime means that if an access token is somehow intercepted or leaked, the window of exposure is tightly bounded. An attacker holding a stolen token has a limited amount of time before it becomes useless. This is significantly safer than long-lived tokens that could be exploited for days or months after compromise.

When an access token expires, the client uses a refresh token to obtain a new access token without re-authenticating from scratch. Refresh tokens have a longer lifetime but are single-use — each use rotates the token, so a stolen refresh token can be used at most once. If the legitimate client uses the refresh token first, the stolen copy becomes invalid. If refresh also fails, the client must re-authenticate entirely through the full OAuth flow. This layered approach means that token compromise at any level has a limited blast radius.

How does refresh token rotation work?

Refresh tokens in StackJack are single-use. When you use a refresh token to obtain a new access token, the old refresh token is immediately and atomically invalidated, and a new refresh token is issued alongside the new access token. This rotation happens on every token refresh, not just periodically.

The atomic invalidation is critical: the old refresh token is consumed and a new one is issued in a single operation that cannot be partially completed. This prevents race conditions where two requests could use the same refresh token simultaneously. In Redis, this is implemented as an atomic read-and-delete operation — the token is retrieved and deleted in one step, ensuring it can only be used exactly once.

The security benefit is significant. If an attacker steals a refresh token, they can use it at most once. If the legitimate client uses it first, the stolen copy becomes permanently invalid. If the attacker uses it first, the legitimate client’s next refresh attempt will fail, serving as a detection signal that something is wrong. Either way, the stolen token has a severely limited useful lifespan compared to non-rotating refresh tokens that could be exploited for the entire token lifetime.

What is Dynamic Client Registration (DCR)?

Dynamic Client Registration (DCR), defined in RFC 7591, allows MCP clients to self-register with StackJack’s OAuth authorization server without manual pre-registration. When an MCP client like Claude Desktop initiates the OAuth flow, it can call the registration endpoint and receive client credentials automatically. This enables seamless setup — users do not need to manually create an MCP client in the Portal before connecting their AI tool.

DCR is rate-limited to prevent abuse. Registration requests are throttled per IP address per hour, preventing automated scripts from creating excessive client registrations. Registered clients receive BCrypt-hashed secrets (same security model as manually created clients) and have a defined expiry period, after which they must re-register. This limits the lifetime of dynamically created credentials and prevents abandoned clients from persisting indefinitely.

From a security perspective, DCR clients are treated identically to manually created clients. They go through the same authentication pipeline, the same authorization checks, and the same rate limiting. The only difference is how they were created — automatically via the registration endpoint instead of manually through the Portal. All the same security controls apply once the client exists.

How does the OIDC integration work for user-level auth?

When an MCP client initiates the OAuth flow, StackJack can redirect to the identity provider (Zitadel) for user login. The user authenticates with Zitadel using their credentials (which StackJack never sees), and Zitadel confirms the user’s identity back to StackJack. StackJack then issues its own JWT containing the authenticated user’s identity — including their Zitadel user ID.

This enables two powerful capabilities. First, per-user tool access controls: the system knows exactly which human is behind each tool call, not just which API client. Each team member can have individual tool allowlists configured by the admin, and these are enforced at the tool execution layer based on the authenticated user’s identity.

Second, per-user credential scoping: each team member can have their own connector credentials. When a user authenticates via OIDC, StackJack loads that specific user’s credentials from Key Vault, ensuring their actions at the connector level are attributed to their individual identity. This is the foundation for enterprise-grade audit trails where every action is traceable to a specific person.

Non-members are denied access even with a valid token — the OIDC flow confirms the user’s identity, but StackJack additionally verifies they are an active owner or member of the tenant. This is fail-closed: a valid Zitadel identity is necessary but not sufficient for access.

What is the authentication flow for the Portal (management UI)?

The Portal uses OpenID Connect (authorization code flow with PKCE) through Zitadel as the identity provider. When you access the Portal, you are redirected to Zitadel to authenticate. After successful login, Zitadel issues tokens that the Portal uses to establish your session. StackJack never sees or handles your login password — that is between you and Zitadel.

Sessions are managed via secure cookies with multiple protection layers: HttpOnly (the cookie is not accessible to JavaScript, preventing XSS-based session theft), Secure (the cookie is only sent over HTTPS, never over unencrypted connections), and SameSite Lax (providing CSRF protection by restricting cross-origin cookie transmission).

Sessions have a limited lifetime with automatic token refresh. If the access token nears expiry, a background refresh is attempted using the stored refresh token. If the refresh fails (for example, if the refresh token has expired or been revoked), the session is immediately invalidated and you must re-login through Zitadel. Cookie encryption keys are shared across application replicas to ensure session consistency regardless of which replica serves your request.

All Portal pages require authentication — there are no unauthenticated management endpoints. Within the Portal, access is further scoped by tenant role (Owner, Admin, or Member), ensuring team members can only perform actions appropriate to their role level.

Access Control & Permissions

Can I restrict which tools an AI agent can use?

Yes. Each MCP client can be configured with an allowed tools list — a specific set of tool names that the client is permitted to call. When an allowlist is configured, only those tools can be executed. Any attempt to call a tool not on the list returns a structured error with the type tool_not_allowed.

This is fail-closed: if an allowlist is configured but empty, zero tools are accessible. If the allowlist data is malformed, it is treated as “deny all” rather than “allow all.” The system never defaults to permissive behavior when explicit restrictions are in place.

Tool restrictions are enforced at the tool execution layer, which means they cannot be bypassed by the AI agent. Even if the AI agent constructs a valid-looking tool call request, the tool access check runs before any connector API is contacted. The check is against the stored allowlist, not against anything the client sends, so it cannot be manipulated by the requesting party.

You configure allowlists through the StackJack Portal, and changes take effect immediately. This gives you granular control over what each AI agent connection can do — one client might have full access for development, while a production client is locked down to specific read-only operations.

How do per-user tool restrictions work?

When team members authenticate via the OIDC flow (for example, through Claude Desktop with their Zitadel login), their individual tool allowlist is enforced. This is configured by the admin through the StackJack Portal — each team member can have a different set of allowed tools.

This enables fine-grained, role-appropriate access control. A junior technician might only get read-only tools — search tickets, list devices, get client details. A senior engineer might get full access including create, update, and delete operations. An intern might get access only to knowledge base search tools. The admin decides what each person can access based on their role and responsibilities.

Per-user restrictions are enforced at the tool execution layer, the same place where per-client restrictions are enforced. When a request comes in with a user identity (from the OIDC-issued JWT), the system checks that specific user’s allowlist. Even if the MCP client itself has broader permissions, the user’s individual restrictions take precedence. If a team member’s AI agent somehow requests a restricted tool, the request is denied before the connector API is contacted. The tool never executes.

What happens if I don’t configure a tool allowlist?

If no allowlist is configured (the default for new clients and new team members), all tools available to your subscription plan are accessible. This is a permissive default designed for easy onboarding — you can start using StackJack immediately without needing to configure tool-level permissions.

Once you configure an allowlist, only the listed tools are available. The transition is immediate: the moment an allowlist is saved in the Portal, only those specific tools can be called. Everything else is denied. There is no gradual transition or grace period.

We recommend configuring allowlists for production use, especially for team deployments. The permissive default is appropriate for initial setup, testing, and evaluation. But for production environments where AI agents are operating on real data, explicitly defining which tools each client or team member can use follows the principle of least privilege — granting only the minimum access needed for each user’s responsibilities. This limits the potential impact if an AI agent behaves unexpectedly or if credentials are compromised.

Can different team members have different tool access levels?

Yes. Each team member can be assigned an individual tool allowlist through the Portal. The admin controls who can access which tools, and each member can have a completely different set of permissions.

This is enforced at the tool execution layer — the deepest enforcement point in the request pipeline. Even if a team member’s AI agent somehow requests a restricted tool (whether through prompt injection, a misconfigured AI workflow, or any other means), the request is denied before the connector API is contacted. The tool never executes, no data flows, and the AI agent receives a structured error explaining that the tool is not in their allowed set.

Practical example: you might configure your lead engineer with access to all HaloPSA tools (search, create, update, delete tickets; manage clients; handle invoices). Your junior technician might get only read-oriented tools (search tickets, get client, list devices). Your dispatch coordinator might get only scheduling and appointment tools. Each person’s AI agent sees only the tools they are allowed to use, creating a role-appropriate experience that matches your organization’s access control policies.

Can I separate read-only from write/destructive operations?

Yes, through tool allowlists. StackJack’s tools include both read operations (search, list, get) and write operations (create, update, delete). You have full control over which tools appear in each client’s or team member’s allowlist.

To create a read-only configuration, include only search, list, and get tools in the allowlist. For example, for HaloPSA you might include halo_search_tickets, halo_get_ticket, halo_list_clients, and halo_get_client while excluding halo_create_ticket, halo_update_ticket, and halo_delete_action.

This gives you complete control over what actions AI agents can perform. You decide the boundary between observation and action. A common pattern is to start with read-only access while evaluating StackJack, then gradually expand to write operations as you build confidence in your AI workflows. You can also maintain separate MCP clients — one read-only for exploratory AI sessions and one with write access for production automation workflows.

What is plan-based tool gating?

Some advanced tools are restricted to higher subscription tiers. The Free plan includes a subset of tools for evaluation purposes. The Pro and Business plans unlock the full tool set for their respective connectors. Each tool has a minimum plan requirement defined in StackJack’s tool registry.

When a user attempts to call a tool that requires a higher plan than their current subscription, they receive a structured error response with the type plan_required. The response includes the tool name, the plan required, and actionable guidance explaining how to upgrade. The AI agent can use this information to inform the user or adjust its approach.

Plan-based gating is enforced before the tool executes — the check happens in the tool execution pipeline, after tool access verification but before the connector API is contacted. This means no API calls are wasted on tools that would be rejected anyway. The gating is based on the subscription record in the database, so upgrading your plan immediately unlocks the additional tools without any configuration changes or restarts.

How does the tool execution pipeline enforce all these checks?

Every tool call passes through a sequential pipeline where each check must pass before the next one runs. The order is strict and cannot be skipped or reordered:

Step 1 — Tool access check: Is this tool in the client’s (or user’s) allowed set? If an allowlist is configured and the tool is not on it, execution stops with a tool_not_allowed error. Step 2 — Plan gating check: Does the subscription plan meet the tool’s minimum tier requirement? If not, execution stops with a plan_required error. Step 3 — Monthly usage check: Has the tenant exceeded their monthly call limit for this connector? If so, execution stops with a rate_limited error.

Step 4 — Execute the tool: Only now does the actual API call to your connector happen. The tool runs, and the response flows back through StackJack to your AI agent. Step 5 — Log the result: The tool name, success/fail status, duration, and any error message are recorded in the usage log. Only successful calls increment the monthly usage counter.

A failure at any step returns a structured JSON error and stops the pipeline. The tool never reaches the connector API unless all checks pass. This layered enforcement means that even if one control were somehow bypassed, the remaining controls would still block unauthorized access.

What are the structured error responses AI agents receive?

When a tool call fails at any point in the pipeline, StackJack returns a structured JSON response specifically designed for AI agent consumption. This is not a generic error page or an unstructured error string — it is machine-readable data that the AI agent can programmatically interpret and act on.

Each error response includes: an error flag (boolean, always true), an error type classification (a machine-readable string like tool_not_allowed, plan_required, rate_limited, not_found, validation_error), a retryable flag (boolean indicating whether the AI should retry the request), the tool name, a human-readable message explaining what went wrong, and actionable guidance suggesting what the AI agent should do next.

This design enables intelligent AI behavior on failure. When an AI agent receives a rate_limited error with retryable: true, it knows to wait and try again. When it receives a plan_required error with retryable: false, it knows retrying is pointless and can inform the user about the plan requirement. When it receives a not_found error with guidance to verify the ID, it can suggest the user check the resource identifier. The AI agent can programmatically decide what to do next rather than blindly retrying or presenting a cryptic error.

MCP Protocol Security

Is MCP inherently insecure?

MCP is a protocol, not a product — like HTTP or SMTP. Whether it is secure depends entirely on how it is implemented. The concerns you may have heard about relate specifically to local stdio MCP servers, where credentials are stored in plaintext JSON config files (like claude_desktop_config.json), there is no authentication layer, and any process on your machine could potentially interact with the server.

StackJack is a fundamentally different implementation. It uses remote authenticated MCP via Streamable HTTP over HTTPS with multi-layer authentication (OAuth 2.0 with PKCE, BCrypt-verified Basic Auth), credentials stored in Azure Key Vault (not config files), per-tenant isolation, rate limiting, and a fail-closed security design where any validation failure results in denial.

The difference is comparable to SQLite on a desktop versus a production database with encryption at rest, role-based access control, audit logging, and network security. Both use SQL, but the security posture is entirely different. MCP as a protocol is sound — what matters is the implementation, and StackJack is built with enterprise-grade security controls at every layer.

What’s the difference between local stdio MCP and remote HTTP MCP?

Local stdio MCP runs the MCP server directly on your machine. It communicates via process stdin/stdout pipes. Credentials for the services it connects to are typically stored in plaintext JSON configuration files (like claude_desktop_config.json), visible to anyone with file access. There is no authentication layer between your AI client and the local server — any process on your machine could potentially interact with it. There is no audit logging, no rate limiting, and no centralized credential management.

Remote HTTP MCP (StackJack) hosts the MCP server in Azure. All communication uses HTTPS with TLS 1.2+ encryption. Credentials are stored in Azure Key Vault with HSM-backed encryption, not in config files. Every request passes through a multi-layer authentication pipeline (OAuth 2.0 with PKCE or BCrypt-verified Basic Auth), followed by authorization checks, rate limiting, and per-tenant isolation. Every tool call is logged with a full audit trail.

These represent fundamentally different security postures. Local stdio is convenient for development and personal use where the risk profile is limited to your own machine. Remote authenticated HTTP is designed for organizational use where credentials must be protected, access must be controlled, and activity must be auditable. StackJack was built from the ground up for the latter scenario.

What is Streamable HTTP transport?

The MCP specification defines multiple transport methods for how AI clients communicate with MCP servers. Stdio pipes data through a local process’s stdin and stdout. Streamable HTTP sends MCP messages as standard HTTP requests over HTTPS — the same protocol that secures your online banking, email, and every other sensitive web application.

With Streamable HTTP, every request is independent, authenticated, and encrypted. There are no persistent connections to manage, no WebSocket upgrade paths to secure, and no long-lived sessions that could be hijacked. Each tool call is a discrete HTTPS request with full authentication headers, processed through StackJack’s security pipeline, and returned as an encrypted HTTPS response.

Streamable HTTP is the most widely supported and most secure MCP transport method. It works with all major MCP-compatible AI clients — Claude Desktop, Claude Code, GitHub Copilot, Cursor, and others. Because it uses standard HTTPS, it benefits from decades of battle-tested TLS security infrastructure, works through corporate firewalls and proxies, and requires no special network configuration.

Does the MCP protocol itself have authentication?

The core MCP protocol specification is transport-agnostic — it defines how tools are discovered and called, not how connections are secured. The stdio transport has no built-in authentication at all; it relies entirely on the operating system’s process isolation. This is one of the main security concerns people raise about MCP.

The MCP OAuth specification adds full OAuth 2.0 authentication to HTTP transport, and StackJack implements it completely. This includes PKCE-enforced authorization code flows, RSA-256 signed JWT access tokens, single-use refresh tokens with rotation, dynamic client registration, and published metadata endpoints for automatic discovery. StackJack’s OAuth implementation follows the MCP specification while adding additional security controls.

StackJack goes beyond what the MCP OAuth spec requires. The spec defines how tokens are issued and validated, but StackJack adds multi-layer authorization (tenant verification, subscription checks, tool allowlists), per-tenant rate limiting, per-connector usage tracking, and a complete audit trail. The MCP protocol provides the framework; StackJack builds enterprise-grade security on top of it.

Why is a hosted MCP server more secure than running your own locally?

A professionally hosted MCP server provides security controls that local installations simply cannot offer. With StackJack, your connector credentials are stored in HSM-backed Azure Key Vault rather than plaintext JSON files on your desktop. Every connection is authenticated through a professional auth pipeline (OAuth 2.0 with PKCE or BCrypt-verified Basic Auth) rather than having no authentication at all. Every tool call is recorded in a centralized audit log rather than disappearing without a trace.

Additional security layers include: rate limiting and abuse prevention at multiple levels (burst, monthly, and per-connector upstream limits) versus no rate limiting on a local server; per-tenant data isolation enforced at the database, cache, and credential layers; continuous updates and patches managed by security-focused engineers versus manual updates that may never happen; and managed infrastructure with TLS termination, health monitoring, and automatic scaling.

This follows the same logic that drives organizations to use managed cloud databases instead of SQLite files, managed email services instead of self-hosted mail servers, and cloud identity providers instead of local password files. The security, reliability, and operational overhead advantages of a professionally managed service are substantial — especially when the alternative involves storing API credentials for your PSA and RMM platforms in unencrypted files on individual workstations.

Is MCP traffic encrypted?

With StackJack, yes — always. All MCP traffic uses Streamable HTTP over HTTPS with TLS 1.2 or higher. The request, response, tool parameters, and returned data are all encrypted in transit. TLS 1.0 and 1.1 are not supported anywhere in StackJack’s infrastructure. This is the same encryption standard used by banks, healthcare systems, and government services.

The encryption extends beyond just the connection between your AI client and StackJack. All upstream connector API calls (to HaloPSA, Autotask, ConnectWise, NinjaRMM, CIPP) also use HTTPS. Database connections require encryption. Redis connections are SSL-only with the non-SSL port disabled. Key Vault access uses HTTPS. There is no unencrypted communication path anywhere in StackJack’s infrastructure.

Local stdio MCP servers do not encrypt traffic because they communicate via process pipes on your local machine — encryption is not applicable to inter-process communication. However, the credentials for those local servers typically sit in plaintext config files, which is a different and arguably more concerning security issue. With StackJack, your data is encrypted in transit at every hop, and your credentials are encrypted at rest in Azure Key Vault.

Can other applications on my machine access my StackJack MCP connection?

Your MCP client (Claude, Cursor, etc.) connects to StackJack over HTTPS using your authenticated credentials. Other applications on your machine cannot intercept this traffic because it is encrypted with TLS. They would need your MCP client credentials — your Client ID and Secret, or your OAuth tokens — to authenticate to StackJack, and those should be stored securely by your MCP client application.

Even if another application somehow obtained your credentials, StackJack’s audit logging would record all activity, and you could immediately revoke the compromised client from the StackJack Portal. If you use the OIDC authentication flow with per-user identity, each user’s access is tracked individually, making unauthorized use detectable.

This is fundamentally more secure than local stdio MCP, where the server runs on your machine and communicates via local process pipes. With local stdio, any application with sufficient permissions could potentially interact with the MCP server process or read the plaintext configuration files containing your connector credentials. With StackJack, your credentials never exist on your local machine — they are in Azure Key Vault, and your local machine only holds the MCP client authentication credentials used to connect to StackJack’s remote server.

AI Safety & Control

Can an AI agent delete or modify data in my PSA/RMM through StackJack?

Only if you have explicitly allowed it. You control which tools each AI agent can access through allowlists configured in the StackJack Portal. If you do not include delete or update tools in the allowlist, the AI cannot call them — period. Even if the AI attempts to call a restricted tool, the request is rejected at StackJack’s tool execution layer before it reaches your connector API.

Many organizations configure their MCP clients with read-only allowlists for general use — search, list, and get operations only. Write access (create, update, delete tools) is granted only to specific, trusted clients used for well-defined automation workflows. This approach follows the principle of least privilege: each AI agent connection gets only the minimum access needed for its intended purpose.

Even when write tools are allowed, additional safeguards apply. Bulk operations are capped at safe item limits per call, preventing a single request from affecting an unreasonable number of records. All tool calls are logged with full audit trails, so you can see exactly what was modified, when, and by which AI client or user. If unexpected write activity occurs, you can immediately revoke the client from the Portal.

Can the AI “go rogue” and perform actions I didn’t intend?

The AI can only call tools that are (1) in your allowlist, (2) available on your subscription plan, and (3) within your monthly usage limit. It cannot discover hidden tools, bypass access controls, or escalate its own permissions. The set of tools an AI agent can use is determined entirely by your configuration in the StackJack Portal — the AI has zero ability to change or expand that set.

If the AI requests a tool that is not on the allowlist, it receives a structured denial response with the error type tool_not_allowed. It does not get to try again with elevated access. There is no mechanism in StackJack for the AI to request permission escalation, negotiate for additional tool access, or bypass the configured restrictions through any means. The access controls are enforced at StackJack’s security layer, not by the AI itself.

This architecture means the AI operates within a strictly bounded sandbox. Even in adversarial scenarios (prompt injection, confused deputy attacks, or unexpected AI behavior), the AI cannot exceed the permissions you configured. The worst case is that the AI calls allowed tools in unexpected combinations — which is why we recommend starting with read-only tool sets and expanding access gradually as you build confidence in your AI workflows.

Can I audit exactly what the AI did through StackJack?

Yes. Every tool call is logged with comprehensive metadata: your tenant ID, the MCP client that made the call, the authenticated user (if using the OIDC flow), the connector type, the exact tool name, whether it succeeded or failed, any error message, and how long the call took. This data is available in your Portal dashboard.

The audit trail provides a complete record of all AI activity through StackJack. You can see exactly which tools were called, when, by which client, and by which user. This enables you to monitor AI agent behavior, identify unusual patterns, verify that agents are operating within expected boundaries, and investigate any incidents after the fact.

Importantly, StackJack logs only audit metadata — tool name, success/fail, duration, and error messages. It does not log tool parameters, API request bodies, or API response content. Your actual PSA/RMM data (ticket details, client information, device records) is never stored in the audit log. This gives you full visibility into what actions were taken without StackJack ever persisting your operational data.

What happens if an AI hallucinates a tool name or invalid parameters?

StackJack validates every tool call before forwarding it to your connector API. If the AI requests a tool that does not exist, it receives a structured error explaining the tool was not found. The request never reaches your connector — it is caught and rejected at StackJack’s tool execution layer.

If parameters are invalid — wrong format, out of range, malformed JSON — input validation catches it and returns a specific, descriptive error message. For example, date parameters must match strict format requirements, enum parameters are checked against allowed value sets, page sizes are clamped to safe maximums, and all JSON is strictly parsed. Each validation failure produces a structured error with helpful context explaining what was wrong and what the valid options are.

These structured error responses are specifically designed for AI agent consumption. They include error type classification, retryability flags, and actionable guidance. When the AI receives a clear explanation of what went wrong, it can self-correct on subsequent attempts — fixing the parameter format, choosing a valid enum value, or using the correct tool name. Invalid requests are contained safely without any impact on your connector systems.

Does StackJack validate tool inputs before forwarding to the API?

Yes, comprehensively. Every tool includes input validation that runs before the request is forwarded to your connector API. Page sizes are clamped to safe maximums to prevent excessive data retrieval — even if the AI requests 10,000 records, the page size is automatically capped. Dates must match strict format requirements, and invalid dates are rejected with clear error messages explaining the expected format.

Enum parameters are validated against defined allowed value sets. If the AI provides an invalid enum value, the error response includes the list of valid options, enabling the AI to self-correct. Bulk operations are capped at safe item limits per call, and individual IDs within bulk requests are validated for correct format. All JSON parameters are strictly parsed — malformed JSON is caught immediately and returned as a structured validation error.

Invalid inputs never reach your connector API. They are caught at StackJack’s validation layer and returned as structured errors with helpful messages that explain what was wrong and how to fix it. This protects your connector systems from malformed requests, prevents unexpected behavior from bad input data, and helps the AI agent learn to provide correctly formatted parameters on subsequent attempts.

Are there limits on bulk or destructive operations?

Yes. Bulk operations (like updating multiple tickets at once) have per-call item limits that cap the number of records a single tool call can affect. This prevents a single AI request from modifying an unreasonable number of records in your PSA or RMM system, regardless of what the AI agent requests.

These limits work in combination with other safety controls. Tool allowlists let you exclude bulk and destructive operations entirely from specific MCP clients or team members. Audit logging records every call, so any bulk operation is fully traceable. Monthly usage limits cap total call volume, and per-minute burst limits prevent rapid-fire requests that could overwhelm your connector APIs.

For organizations concerned about destructive operations, the recommended approach is to start with read-only tool sets (search, list, get operations) and only add write tools after evaluating your AI workflows. When you do add write access, begin with single-record operations (create one ticket, update one asset) before enabling any bulk operations. This layered, gradual approach — combined with per-call item limits and full audit logging — provides multiple layers of protection against unintended large-scale changes.

Can I see a full history of all tool calls made against my account?

Yes. The StackJack Portal provides a usage dashboard showing every tool call made against your account. Each entry includes the timestamp, tool name, connector type, success or failure status, call duration, and which MCP client or authenticated user made the call. This gives you complete visibility into all AI agent activity.

This data is retained for billing reconciliation and audit purposes. Usage logs are stored in the database with efficient indexing for querying by tenant and date range, enabling you to review historical activity patterns. Only successful tool calls count against your monthly usage limits, so you can also track your actual billable usage versus total call volume.

You can use this history to monitor AI agent behavior, identify patterns (which tools are used most, what time of day activity peaks, which users are most active), verify that agents are operating within expected boundaries, and investigate any unusual activity. For organizations with compliance requirements, this audit trail provides documented evidence of exactly what AI agents accessed and when.

Who is responsible if an AI agent causes damage through a tool call?

This follows a shared responsibility model. StackJack provides the security infrastructure: the access control layer (allowlists, plan gating), the authentication pipeline (OAuth 2.0, Basic Auth), the audit trail (comprehensive usage logging), tenant isolation, rate limiting, and input validation. StackJack ensures these security mechanisms function correctly and reliably.

You configure which tools are accessible and to whom. You define the allowlists, you invite team members and set their permissions, and you decide which connectors to enable and at what plan level. The AI agent operates within the boundaries you set. This is analogous to a cloud provider securing the infrastructure while you secure your workload configuration — each party is responsible for their layer.

We strongly recommend a gradual, cautious approach: start with read-only tool sets, audit the AI agent’s behavior through the usage dashboard, expand to single-record write operations when comfortable, and enable bulk operations only with full confidence in the workflow. Configure per-user tool restrictions so each team member’s AI agent has only the access appropriate for their role. Use the audit trail to review activity regularly. These practices minimize risk while maximizing the value of AI-assisted MSP operations.

Tenant Isolation

Can other StackJack tenants access my data or credentials?

No. Tenant isolation is enforced at every layer of StackJack’s architecture. Every database query includes your tenant ID — there are no queries that can return another tenant’s data. Your credentials are stored as separate secrets in Azure Key Vault, scoped to your tenant. Your cache entries are keyed by your tenant ID. Your rate limits are tracked independently.

This is architectural isolation, not just access control. It is not a matter of checking permissions before accessing shared data — the data itself is partitioned so that one tenant’s operations physically cannot reference another tenant’s records. Another tenant’s requests cannot access your data, your credentials, or your configuration because the isolation is built into how every component stores and retrieves information.

The isolation spans all infrastructure layers: SQL Server (tenant ID in every query), Azure Key Vault (separate secrets per tenant), Redis cache (tenant ID in every cache key), and rate limiting (independent counters per tenant). Even if a hypothetical bug affected one layer, the remaining layers maintain independent isolation. This defense-in-depth approach ensures that no single point of failure can compromise tenant boundaries.

How is tenant isolation enforced at the database level?

Every query in the application includes the tenant ID in the WHERE clause. This is not optional and not configurable — it is how the data access layer is structured. There are no admin endpoints that query across tenants, no reporting functions that aggregate multi-tenant data, and no background jobs that process multiple tenants in a shared context.

The tenant ID is established during Layer 1 of the authentication pipeline (tenant resolution) and is used throughout the entire request lifecycle. When your request is authenticated, StackJack resolves your tenant identity and carries it through every subsequent operation — every database query, every cache lookup, every Key Vault access, and every rate limit check uses that authenticated tenant identity.

This is not a policy that could be accidentally misconfigured — it is how the code is structured. The application’s data access patterns are built around tenant-scoped queries from the ground up. All child entities (connector credentials, subscriptions, MCP clients, usage logs, team members) belong to a tenant and are always accessed through tenant-scoped queries. Deleting a tenant cascade-deletes all associated data, ensuring no orphaned records from other tenants are ever accessible.

How is tenant isolation enforced in caching and rate limiting?

All cached data — including OAuth tokens for upstream APIs and credential payloads from Key Vault — includes the tenant ID in the cache key. A cache lookup for tenant A will never return tenant B’s data because the keys are structurally different. This is not a permission check on shared data; the cache entries are inherently separate by design.

Rate limit counters are tracked independently per tenant per connector. Both burst limits (per-minute) and monthly usage limits are scoped to your tenant and your specific connector subscription. One tenant hitting their rate limit has absolutely zero effect on any other tenant’s access, performance, or available capacity. Each tenant operates within their own independent allocation.

This tenant-scoped caching also provides performance isolation. Cache eviction (for example, when credentials are rotated) only affects the specific tenant whose data changed. Other tenants’ cached tokens and credentials remain unaffected. Similarly, if one tenant generates high request volume, their rate limiting activates independently without impacting the experience for other tenants on the platform.

What if there’s a software bug in tenant isolation?

Defense in depth means a bug in one layer does not automatically compromise isolation. StackJack enforces tenant isolation through multiple independent mechanisms at the database, Key Vault, cache, and rate limiting layers. Each mechanism operates independently — a bug in one does not disable the others.

For example, even if a hypothetical database query bug occurred, your credentials are stored as separate Key Vault secrets per tenant — a database bug cannot leak Key Vault secrets because they are in an entirely separate system with its own access controls and HSM-backed encryption. Similarly, cache keys include tenant IDs as a structural component, so even a database issue would not cross-contaminate cached credentials or tokens.

This layered approach is the same defense-in-depth principle used in critical infrastructure security. No system can guarantee zero bugs, but architectural redundancy ensures that no single bug can compromise the entire isolation boundary. Each layer provides independent protection, and an attacker (or a software defect) would need to simultaneously compromise multiple independent systems to breach tenant isolation.

Are credentials shared between tenants?

Never. Each tenant’s connector credentials are stored as entirely separate secrets in Azure Key Vault. There is no shared credential pool, no common credential store, and no mechanism by which one tenant’s credentials could be accessed by another tenant’s request.

When your request is authenticated, StackJack resolves your tenant identity and loads only your tenant’s credentials from Key Vault. The credential lookup is scoped by the authenticated tenant identity established in the authentication layer. The application has no function, endpoint, or code path that would load another tenant’s credentials for your request.

Credentials can be further scoped to individual users within your tenant. Each team member’s connector credentials are stored as separate Key Vault secrets, distinct from the shared tenant credentials and from other team members’ credentials. This per-user credential scoping provides an additional layer of isolation within your own organization, enabling per-user audit attribution at the connector level and ensuring that one team member’s credential rotation does not affect another’s access.

Infrastructure & Hosting

Where is StackJack hosted?

Entirely on Microsoft Azure. The application runs on Azure Container Apps. The database is Azure SQL. Secrets are stored in Azure Key Vault. Caching and rate limiting use Azure Redis Cache. Support attachments use Azure Blob Storage. Container images are stored in Azure Container Registry. Telemetry goes to Azure Application Insights.

No non-Azure services are involved in the data path. Your connector credentials, account data, usage logs, and all operational traffic flow exclusively through Azure infrastructure. There are no third-party data processors, no external analytics services with access to your data, and no CDN or proxy services that handle unencrypted traffic.

Azure is used by the majority of enterprise organizations globally and meets the compliance requirements of industries including healthcare (HIPAA), finance (SOC 2, PCI DSS), and government (FedRAMP). While StackJack’s own compliance certifications are in progress, the underlying infrastructure benefits from Azure’s extensive security certifications and the physical security, redundancy, and operational practices of Microsoft’s data centers.

What Azure services do you use and how are they secured?

Each Azure service in StackJack’s stack has specific security configurations applied. Azure SQL uses Transparent Data Encryption (TDE) for data at rest, encrypted connections are enforced on all database traffic, and TLS 1.2 is the minimum protocol version. Azure Key Vault uses RBAC authorization (not legacy access policies) for precise permission control, with soft delete and purge protection enabled to prevent accidental or malicious secret deletion.

Azure Redis Cache has SSL-only connections with the non-SSL port disabled, enforcing TLS 1.2 minimum for all cache communication. Azure Container Apps uses system-assigned managed identities for Key Vault authentication (no stored passwords), HTTPS-only ingress with insecure HTTP connections rejected, and automatic health-based scaling that routes traffic only to verified-healthy instances.

Azure Blob Storage uses server-side encryption for support attachments. Azure Container Registry stores container images securely. Application Insights provides telemetry and monitoring without capturing personally identifiable information. Every service is configured to enforce encryption in transit and at rest, use the strongest available authentication methods, and follow the principle of least privilege for inter-service communication.

Is all data encrypted in transit?

Yes. All external traffic uses HTTPS with TLS 1.2 or higher. This includes every connection between your AI client and StackJack, and every connection between StackJack and your connector APIs (HaloPSA, Autotask, ConnectWise, NinjaRMM, CIPP). TLS 1.0 and 1.1 are not supported anywhere in the infrastructure.

Internal service communication is also encrypted. Database connections require encryption and reject unencrypted connections. Redis connections are SSL-only with the non-SSL port completely disabled. Key Vault access uses HTTPS exclusively. All upstream connector API calls use HTTPS. The Azure platform secures internal service-to-service communication.

There is no unencrypted communication path anywhere in StackJack’s infrastructure. From the moment your AI client sends a tool call request to the moment the response arrives back, every network hop is encrypted. This applies equally to the MCP traffic carrying tool calls, the credential retrieval from Key Vault, the cache operations in Redis, and the audit log writes to the database.

Is all data encrypted at rest?

Yes. Azure SQL uses Transparent Data Encryption (TDE), which means all data, transaction logs, and backups are encrypted at rest using AES-256 encryption. This encryption is automatic, always-on, and managed by the Azure platform with no performance impact to the application.

Azure Key Vault uses HSM-backed encryption for all stored secrets, including your connector credentials and the OAuth signing key. Azure Redis Cache data is encrypted at rest by the Azure platform. Azure Blob Storage (used for support ticket attachments) uses server-side encryption. Every data store in StackJack’s architecture encrypts data at rest.

All of this encryption is managed by the Azure platform, not by application code. There is no unencrypted data at rest anywhere in the infrastructure. Combined with encryption in transit (TLS 1.2+ on all connections), your data is encrypted at every stage of its lifecycle — whether it is being transmitted between services, stored in a database, cached in Redis, or held in Key Vault.

What TLS version do you require?

TLS 1.2 is the minimum across all services. TLS 1.0 and 1.1 are not supported anywhere in StackJack’s infrastructure. This minimum is enforced on all external connections (user traffic and API calls), database connections (Azure SQL), cache connections (Azure Redis), and secret management access (Azure Key Vault).

TLS 1.2 is the industry standard minimum for secure communications. It is required by most compliance frameworks including PCI DSS, HIPAA, and SOC 2. Older TLS versions (1.0 and 1.1) have known vulnerabilities and have been deprecated by major browser vendors, cloud providers, and standards bodies. By enforcing TLS 1.2 minimum, StackJack ensures that all connections use modern, vetted cryptographic protocols.

TLS 1.3 is supported where the connecting client and Azure service both support it, providing even stronger security with improved handshake performance. However, TLS 1.2 remains the enforced minimum to ensure broad compatibility with all MCP clients while maintaining a strong security baseline. No connection using a protocol version below TLS 1.2 will be accepted by any component of StackJack’s infrastructure.

How does StackJack scale under load?

StackJack runs on Azure Container Apps with automatic horizontal scaling. The platform monitors request concurrency and scales between minimum and maximum replica counts based on load. When traffic increases, new container replicas are started automatically. When traffic decreases, excess replicas are removed. This ensures the service handles traffic spikes without manual intervention.

Each replica is independently healthy and shares no local state. All state is stored in external services: the database (Azure SQL), cache (Redis), and secrets (Key Vault). New replicas start handling traffic only after passing health checks — a startup probe verifies the container is initialized, and a readiness probe confirms database and Redis connectivity. No requests are routed to an instance until it is fully operational.

This stateless architecture also supports safe scaling and deployments. Replicas can be added or removed at any time without session affinity concerns (for the MCP server). Rate limiting counters and OAuth tokens are stored in Redis, so they are consistent across all replicas. If a replica becomes unhealthy, a liveness probe detects it and the platform automatically restarts the container — all without impacting other replicas or in-flight requests on healthy instances.

Do you use managed identities instead of stored passwords for infrastructure?

Yes. Both application containers (the MCP Server and the Portal) use system-assigned managed identities to authenticate to Azure Key Vault. This means there are no Key Vault passwords, connection strings, or API keys stored in configuration files, environment variables, or application code. Authentication is handled cryptographically by the Azure platform itself.

If an attacker obtained the application’s source code and all of its configuration, they would find no credentials for Key Vault. The managed identity is tied to the specific Azure Container Apps instance — it cannot be exported, copied, or used from outside the Azure environment. This eliminates an entire category of credential theft attacks: there are simply no infrastructure secrets to steal from the application layer.

Managed identities represent Azure’s recommended best practice for service-to-service authentication. They eliminate the credential management lifecycle entirely — no rotation schedules, no expired secrets, no accidental exposure in logs or error messages. The Azure platform handles the cryptographic handshake transparently, and the application simply requests access using its platform-verified identity. This is the most secure method available for Azure service authentication.

What happens during a StackJack deployment — is there downtime?

No. Deployments use rolling updates — new container revisions are started alongside existing ones. Traffic continues flowing to the current revision while the new revision initializes. The new revision only starts receiving traffic after it passes all health checks: a startup probe confirms the container is initialized, and a readiness probe verifies database connectivity and Redis availability.

Old revisions continue serving traffic until the new ones are fully ready and verified. This provides zero-downtime deployments. There is no maintenance window, no service interruption, and no period where tool calls would fail due to a deployment in progress. Your AI agents continue operating normally throughout the entire deployment process.

The health check system is comprehensive. The readiness probe performs live checks against the database and Redis to ensure the new revision can actually handle requests, not just that the container started. The startup probe allows sufficient time for database warmup (Azure SQL Serverless may need time to wake from auto-pause). Only after all health checks pass does the platform route traffic to the new revision and drain the old one. If a new revision fails health checks, the deployment is automatically rolled back and the previous healthy revision continues serving all traffic.

Reliability & Rate Limiting

What happens if StackJack goes down?

StackJack is a gateway, not a data store. An outage means AI agents temporarily can’t use MCP tools — but that’s the full extent of the impact. Your PSA/RMM systems (HaloPSA, Autotask, ConnectWise, NinjaRMM, CIPP) continue operating normally and independently. You can always access them directly through their native web interfaces, desktop clients, and mobile apps.

No data is lost because StackJack doesn’t store your operational data. There is no queue of pending operations that could be lost, no cached business data that could become stale, and no synchronized state that could drift. StackJack is a stateless pass-through — when it’s available, it forwards requests; when it’s not, your systems are simply not receiving AI-initiated API calls.

When service resumes, your AI agents can immediately reconnect and start making tool calls again. There is no resynchronization step, no data recovery process, and no manual intervention required. Everything picks up exactly where it left off because there was nothing to lose in the first place.

Does a StackJack outage affect my PSA/RMM systems?

No. StackJack has zero write access to your systems’ configuration or availability. It calls their APIs on your behalf — that’s the entire relationship. If StackJack is down, those APIs simply don’t receive calls from StackJack. Your PSA/RMM systems are completely independent.

Their uptime, data, and functionality are entirely unaffected by anything that happens on StackJack’s side. Your technicians can still create tickets, manage devices, and access client data through the same native interfaces they always use. StackJack never modifies system configuration, never installs agents on your infrastructure, and never creates dependencies that could cascade into your operational tools.

This is a deliberate architectural decision. StackJack is designed as a completely optional, additive layer. It gives your AI agents the ability to interact with your MSP tools, but removing it or experiencing an outage has exactly one consequence: AI agents can’t make tool calls until service resumes. Nothing else changes.

How does StackJack handle upstream API outages or errors?

Every tool call includes structured error handling with error classification, retryability flags, and actionable guidance. If a connector API returns an error or times out, the AI agent receives a clear explanation of what happened and whether retrying is appropriate — not a cryptic failure message.

StackJack’s HTTP clients include multiple resilience patterns that operate automatically: automatic retries with exponential backoff for transient failures (so the AI agent doesn’t have to manually retry), circuit breakers that prevent cascading failures by temporarily stopping requests to an API that’s returning errors, and configurable timeouts that prevent tool calls from hanging indefinitely when an upstream API is unresponsive.

These resilience patterns ensure graceful degradation. If HaloPSA is experiencing issues, your NinjaRMM and CIPP connectors continue operating normally. If a connector API is temporarily overloaded, the circuit breaker protects it from being hammered with retries. Every error is surfaced to the AI agent as a structured JSON response with enough context to make intelligent decisions about how to proceed.

How does rate limiting work?

StackJack enforces rate limits at multiple independent layers. Per-tenant burst limits prevent request flooding within short time windows, protecting shared infrastructure from any single tenant’s sudden traffic spike. Per-connector monthly caps enforce plan-based usage limits: Free gets 100 calls per month, Pro gets 5,000, and Business gets 50,000 — tracked independently per connector.

Upstream API rate limiting protects your connector instances from exceeding vendor-imposed thresholds. Each connector has specific limits calibrated to the upstream API’s published rate limits. This prevents StackJack from overwhelming your HaloPSA, Autotask, ConnectWise, NinjaRMM, or CIPP instance — even if an AI agent attempts rapid-fire tool calls.

Each rate limiting layer operates independently. When any limit is hit, the AI agent receives a structured response with retry guidance including when to try again. Rate limit headers are included on every response so AI agents can proactively manage their request pacing. The system is designed to be transparent and predictable — your AI agent always knows where it stands relative to its limits.

What happens when I hit my monthly tool call limit?

Your AI agent receives a structured error explaining the limit has been reached, including your current usage count and information about upgrading. The response is specifically formatted for AI agent consumption, so the agent can communicate the situation clearly to you rather than failing silently.

Only successful tool calls count against your limit. Failed calls — authentication errors, validation errors, upstream API errors — do not consume your monthly quota. This ensures you’re only billed for tool calls that actually delivered value. If a tool call fails due to an upstream issue and needs to be retried, the failed attempt doesn’t count.

Your direct access to your PSA/RMM systems is never affected by StackJack rate limits. You can always access HaloPSA, Autotask, ConnectWise, NinjaRMM, and CIPP through their native interfaces regardless of your StackJack usage. You can also upgrade your plan at any time through the StackJack Portal to increase your limit, and the new limit takes effect immediately.

How do you prevent one tenant from degrading service for others?

Complete isolation at every layer. Rate limits are per-tenant — one tenant’s heavy usage doesn’t consume another’s quota. Burst limits prevent any single tenant from overwhelming shared infrastructure. Upstream API rate limiting is per-connector-per-tenant, so one organization’s aggressive AI agent can’t exhaust another organization’s connector API capacity.

The application scales automatically under load. When request volume increases, additional container replicas are spun up to handle the traffic. This means even if multiple tenants are making heavy use of the system simultaneously, the infrastructure expands to accommodate the load rather than forcing tenants to compete for fixed resources.

Because StackJack is stateless with no shared data between tenants, there are no contention points where one tenant’s activity can impact another. There are no shared database locks, no shared cache keys, no shared queues. Each tenant’s requests are processed independently, rate-limited independently, and isolated at every level from authentication through execution. The noisy neighbor problem is eliminated by design.

Compliance & Legal

Are you SOC 2 Type II certified?

SOC 2 Type II certification is on our compliance roadmap. StackJack was built by engineers whose other products have successfully completed SOC 2 Type II audits — built on the same .NET stack, the same Azure infrastructure, and the same security patterns we use here. We’re confident in the outcome when we pursue certification.

The security controls described on this page — Key Vault credential storage, fail-closed authentication, tenant isolation, encryption everywhere, and audit logging — are consistent with SOC 2 requirements across the Trust Service Criteria (Security, Availability, Confidentiality, and Processing Integrity). These aren’t aspirational controls we plan to implement; they are the actual implemented architecture.

If you require SOC 2 certification as a prerequisite for vendor approval, we understand. We’re happy to walk through our security architecture in detail, answer specific questions from your security team, and provide a timeline for our certification process. Contact us at ceej@stackjack.io to discuss your specific compliance requirements.

Are you GDPR compliant?

StackJack’s architecture is GDPR-friendly by design. We minimize data collection to only what’s needed to operate the service. We don’t store customer operational data thanks to our pass-through architecture. We support data deletion requests with cascade deletion of all tenant data. And all infrastructure runs on Azure, where you can choose the deployment region.

The personal data we hold is limited to account information (name, email address) and usage metadata (which tools were called, success/failure status, timing). We do not collect, store, or process your PSA/RMM data, AI conversation history, or tool call content. This minimal data footprint means the scope of any GDPR request is inherently limited.

Account data can be deleted on request — a tenant deletion cascades through all associated records in the database, removes secrets from Key Vault, and cache entries expire naturally. We don’t use your data for marketing, don’t sell it to third parties, and don’t share it with advertisers. Our business model is subscription revenue, not data monetization.

Are you HIPAA compliant? Can you sign a BAA?

StackJack is not currently HIPAA certified and we cannot sign a Business Associate Agreement (BAA) at this time. If your organization handles Protected Health Information (PHI) through your PSA/RMM systems, please consult your compliance team before using StackJack.

That said, StackJack’s pass-through architecture means we don’t store your operational data. When an AI agent retrieves a ticket or device record, that data flows through StackJack but is never persisted, cached, or logged. However, PHI may transit through our systems during tool calls, and transiting data may still fall under HIPAA requirements depending on your compliance team’s interpretation.

We take this seriously and would rather be transparent about our current status than overstate our compliance posture. If HIPAA compliance is a requirement for your organization, we recommend discussing your specific use case with your compliance team and contacting us at ceej@stackjack.io so we can provide technical details about our data handling architecture to support their assessment.

Do you have penetration test reports?

We’re planning formal penetration testing as part of our compliance roadmap. In the meantime, the security architecture described on this page represents defense-in-depth that addresses the most common attack vectors: Azure Key Vault for secrets management, BCrypt hashing for stored credentials, fail-closed multi-layer authentication, complete tenant isolation, and TLS everywhere.

StackJack is built on the same .NET and Azure stack that has passed SOC 2 Type II audits for our other products. The security patterns — managed identities, Key Vault integration, RBAC authorization, encrypted connections — are consistent across our product line and have been validated through those audit processes.

We’re transparent about where we are in our compliance journey. We’d rather be honest about not yet having a formal pentest report than point to a years-old assessment that doesn’t reflect the current codebase. When we complete penetration testing, the results will inform continuous improvement of our security posture. Contact us at ceej@stackjack.io if you have specific security concerns you’d like to discuss.

Who is the legal entity behind StackJack?

StackJack is a product of MSP Automator Labs, LLC, a New Jersey limited liability company doing business as StackJack.io. The company is founded and operated by Ceej, one of the most experienced HaloPSA implementation specialists and the creator of BillingBot and QuantumOps.

MSP Automator Labs is a focused product company serving the managed service provider industry. We’re not a venture-backed startup trying to be everything to everyone — we build specialized tools for MSPs because that’s the industry we know. This focus means our security decisions are informed by deep understanding of how MSPs actually operate, what their compliance requirements look like, and what risks matter most in their environment.

You can reach the company directly at ceej@stackjack.io. We believe in being accessible and accountable to our customers. When you contact us, you’re reaching the people who actually build and operate the product, not a support queue that routes to a call center.

Do you carry cyber liability insurance?

For current details about our insurance coverage, please contact us at ceej@stackjack.io. We take our responsibility to customers seriously and maintain appropriate coverage for a company of our size and stage.

We understand that cyber liability insurance is an important consideration for vendor security assessments, particularly in the MSP industry where your clients depend on the security of your entire tool chain. We’re happy to discuss our coverage details directly with your procurement or risk management team as part of a vendor review process.

Can you fill out our vendor security questionnaire?

Yes. This security page is designed to answer the most common questions from vendor security questionnaires. Most standard questionnaires — including SIG, CAIQ, and VSAQ formats — can be substantially answered by referencing the information on this page, covering authentication, encryption, data handling, access control, infrastructure, and incident response.

For formal questionnaire completion, contact us at ceej@stackjack.io. We’re happy to work through your organization’s specific security review process. We respond to questionnaires promptly because we know they’re often on the critical path to vendor approval, and we’d rather unblock your team quickly than let a questionnaire sit in a queue.

We believe that being thorough and transparent in security questionnaires builds trust more effectively than vague answers or marketing language. When we answer a question, we provide specific technical details about our actual implementation, not aspirational statements about what we plan to do someday.

What is your incident response process?

If we detect a security incident, our response follows a structured process: (1) Immediately assess scope and contain the threat. (2) Identify affected tenants and data. (3) Notify affected customers promptly via email. (4) Provide clear information about what happened, what data was affected, and what steps we’re taking. (5) Implement fixes and preventive measures. (6) Provide a post-incident report.

Our architecture limits the blast radius of any potential incident. Tenant isolation means a breach affecting one tenant doesn’t automatically compromise others. Key Vault credential storage means connector secrets aren’t exposed even if the application database is compromised. BCrypt hashing means MCP client secrets can’t be recovered from stored hashes. These architectural boundaries contain damage and give us time to respond.

We believe in transparency during incidents. You’ll receive clear, honest communication about what happened, not vague statements designed to minimize the appearance of impact. Our goal is to give you enough information to make informed decisions about your own security posture — including whether you need to rotate credentials, notify your own customers, or take other protective actions.

How will I be notified of a security incident?

Via email to the email address associated with your StackJack account. We commit to prompt notification — we won’t wait weeks to tell you about an issue. When an incident is identified, affected customers are notified as soon as we have enough information to provide actionable guidance.

Notifications will include: what happened (a clear, non-technical explanation of the incident), what data was affected (if any), what actions you should take (e.g., rotating connector credentials, reviewing usage logs), and what we’re doing to prevent recurrence. Each notification is designed to give you everything you need to assess and respond to the situation from your side.

We believe transparency builds trust, even when the news isn’t good. The MSP industry runs on trust — your clients trust you with their infrastructure, and you need to trust your tool vendors with your operational data. We’d rather over-communicate during an incident and maintain that trust than stay silent and hope nobody notices. If we make a mistake, you’ll hear about it from us first, not from a news article.

Team & Account Management

How do team invitations and member access work?

Admins can invite team members via email through the Portal. When a member accepts the invitation, they set up their own authentication — they don’t share the admin’s credentials. Each team member gets their own identity and their own login, ensuring clean separation of access from day one.

The admin configures which tools each member can access via per-user tool allowlists. This means you can give a junior technician access to read-only tools like ticket search and device lookup, while giving a senior engineer access to more powerful tools. Members authenticate to StackJack via the OIDC flow (e.g., logging in through Claude Desktop with their Zitadel account), and their individual restrictions are enforced on every tool call.

This design ensures that team growth doesn’t mean security compromise. Adding a new team member is a controlled, auditable process: the admin sends an invitation, the member creates their own credentials, and the admin configures their tool access. There are no shared passwords, no shared API keys, and no implicit access grants. Every member has exactly the access they need and nothing more.

What roles are available and what can each role do?

Three roles are available. Owner has full control over the tenant, including billing, connector configuration, team management, and all settings. The Owner is the person who created the StackJack account and has ultimate authority over the entire tenant.

Admin can manage team members, configure connector credentials, and manage MCP clients. Admins have operational control over the tenant but do not have billing access. This role is appropriate for senior team members who need to manage the StackJack deployment without needing to change subscription plans or payment methods.

Member can use MCP tools within the boundaries set by their admin-configured allowlist. Members cannot change connector credentials, invite other members, or modify system configuration. Roles are enforced at the Portal level for management actions and at the MCP execution level for tool calls, ensuring consistent access control regardless of how the user interacts with StackJack.

Can I revoke a team member’s access instantly?

Yes. Removing a team member through the Portal immediately prevents them from accessing any StackJack tools. Their OIDC tokens will fail validation on the next request because the system verifies active membership status during authentication. This is not a delayed or eventual action — it takes effect on the very next request.

This instant revocation is possible because StackJack checks membership status on every MCP request, not just at login time. Even if a removed member has a technically valid JWT token, the system will reject it because the underlying membership no longer exists. There is no window of continued access after removal, no cache that needs to expire, and no token that remains valid.

This capability is critical for MSP security. When an employee leaves or changes roles, you need immediate, definitive access revocation — not a promise that access will be removed “within 24 hours” or “at the next sync.” StackJack gives you that control because we verify membership in real-time, on every single request.

What happens to a member’s credentials and access when they leave?

When a team member is removed, multiple things happen. Their Portal access is revoked immediately — they can no longer log in to the management interface. Any active OIDC sessions are invalidated because membership is checked on every MCP request, so even existing tokens stop working immediately.

If the removed member had per-user connector credentials, the admin can remove those credentials from Key Vault through the Portal. This ensures the departed member’s individual credentials for upstream APIs like HaloPSA or ConnectWise are cleaned up as part of the offboarding process.

The member’s historical usage logs are retained for audit purposes — you can still see what tools they called and when, which is important for compliance and post-departure review. But their active access stops instantly. There is no grace period, no lingering session, and no cached credential that continues working after removal. The separation is clean and immediate.

Can I see which team member made which tool call?

Yes, when using OIDC authentication (the recommended flow for team deployments). Each tool call is logged with the authenticated user’s identity, not just the tenant ID. The Portal dashboard shows which member called which tool, when, and whether it succeeded. This enables complete per-user audit trails.

This visibility helps identify if a specific member’s AI agent is behaving unexpectedly — perhaps making unusual tool calls, calling tools outside their normal workflow, or consuming disproportionate usage. It also provides the audit evidence that compliance frameworks like SOC 2 require: the ability to answer “who did what, when, and from where.”

Per-user attribution is a key advantage of the OIDC authentication flow over shared MCP client credentials. With shared credentials, you can see that a tool was called by a specific MCP client, but you can’t distinguish between team members using that client. With OIDC, every request carries the individual user’s identity, giving you the granular visibility that professional team deployments require.

How does the Portal authentication protect my management session?

The Portal uses OpenID Connect through Zitadel with PKCE protection. This is the industry-standard authentication protocol used by major platforms and recommended by security frameworks. PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks that could allow an attacker to hijack your login session.

Sessions are managed via secure cookies with multiple protective flags: HttpOnly means the cookie is not accessible to JavaScript, preventing cross-site scripting (XSS) attacks from stealing your session. Secure means the cookie is only sent over HTTPS, preventing interception on unencrypted connections. SameSite Lax provides CSRF protection by restricting when the cookie is sent in cross-site requests.

Sessions have a limited lifetime and automatically refresh the underlying tokens in the background. If a token refresh fails — for example, because the identity provider session has expired or been revoked — the Portal session is immediately invalidated and you must re-login. Cookie encryption keys are consistent across application replicas, ensuring your session works seamlessly even if your requests are handled by different backend instances.

Ready to Connect Your MSP Stack?

Start with the free tier — 100 tool calls per month, no credit card required.