# HeyAI Private Azure Deployment

This package deploys HeyAI into a customer's Azure subscription. The customer owns the API, UI, PostgreSQL database, embeddings/vectors, connector credentials, logs, and AI keys. HeyAI does not receive project data or telemetry by default.

## HeyAI Control Plane

Private deployments use a small HeyAI control-plane connection so customers can keep receiving licensed updates without giving HeyAI access to project data.

The control plane can receive:

- License activation/check-in metadata: deployment ID, version, tenant/subscription IDs, region, health state, and support-access state.
- Update metadata requests: latest supported package version and release bundle URL.
- Optional `metadata_only` product usage counters such as `analyze_user_story` or `ask_heyai` counts.

The control plane must not receive:

- Work item titles, descriptions, acceptance criteria, comments, source code, embeddings, vectors, prompts, answers, connector credentials, logs containing project content, or AI keys.

Set `-HeyAiTelemetryMode disabled` during deployment when the customer wants no usage counters sent back to HeyAI. License/update checks can still be run manually from a customer pipeline.

## What Gets Deployed

- Azure App Service Linux for the HeyAI API.
- Azure Static Web Apps for the HeyAI UI.
- Azure Database for PostgreSQL Flexible Server with `pgcrypto` and `vector` enabled.
- Azure Key Vault for database and AI secrets.
- System-assigned managed identity for API access to Key Vault.
- Log Analytics and Application Insights in the customer subscription.

The v1 private package does not deploy HeyAI MCP. Hosted HeyAI MCP is for hosted HeyAI projects only and must not be used to access customer-private project data. Customers that need Copilot or MCP access to private deployment data should deploy a customer-owned MCP service in their Azure subscription, pointed at the private HeyAI API and protected by the customer's Entra tenant.

The v1 package uses secure public endpoints. Private endpoints and VNet-only deployment are intentionally left for a later enterprise template.

## What Is In This Release Bundle

Customers do not need HeyAI source repository access. The release bundle contains:

- `release-manifest.json`, the package version and artifact map.
- `infra/` Bicep infrastructure templates.
- `scripts/` PowerShell deployment and validation scripts.
- `artifacts/api/heyai-api.zip`, the compiled HeyAI API package.
- `artifacts/ui/`, the static HeyAI UI files.
- `artifacts/database/schema.sql`, `seed.sql`, and versioned migration folders.
- `artifacts/ado-extension/`, when a private Azure DevOps extension VSIX is included.

## Prerequisites

- Azure CLI authenticated to the customer's subscription.
- Node.js/npm for Static Web Apps CLI and optional Azure DevOps extension packaging.
- `psql` for schema migration, or the .NET SDK so the migration script can use its built-in Npgsql fallback.
- For UI deployment, `@azure/static-web-apps-cli` is invoked through `npx`.
- An Azure OpenAI deployment or an OpenAI API key.
- A HeyAI private deployment license key.
- A Microsoft Entra app registration for the private HeyAI UI if users should sign in with Microsoft.
- Optional Azure Communication Services Email settings if project owners should send teammate notification emails from a private deployment. Team access works without email.

## Recommended: Auto Install Or Update

Use the top-level deployment script for the normal path:

```powershell
.\private-deploy\scripts\heyai-deploy.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -EnvironmentName "prod" `
  -AppName "heyai" `
  -EntraClientId "<customer-entra-app-client-id>" `
  -EntraTenantId "<customer-tenant-id>" `
  -AiProvider "azure_openai" `
  -AzureOpenAiEndpoint "https://contoso-openai.openai.azure.com" `
  -AzureOpenAiDeployment "heyai-gpt"
```

The script reads `release-manifest.json`, detects whether a HeyAI deployment already exists in the resource group, and plans one of these actions:

- Fresh install when no complete deployment exists.
- Update when API/UI/PostgreSQL resources are already present.

Before changing resources, it prints the detected action, package version, target resources, and asks for confirmation. Use `-WhatIf` for a dry run and `-Force` for approved CI/CD pipelines.

Advanced admins can still run the lower-level scripts below.

## 1. Deploy Infrastructure

Azure OpenAI is the recommended enterprise mode:

```powershell
.\private-deploy\scripts\deploy-private.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -Location "centralindia" `
  -StaticWebAppLocation "eastasia" `
  -EnvironmentName "prod" `
  -AppName "heyai" `
  -EntraClientId "<customer-entra-app-client-id>" `
  -EntraTenantId "<customer-tenant-id>" `
  -HeyAiTelemetryMode "metadata_only" `
  -AiProvider "azure_openai" `
  -AzureOpenAiEndpoint "https://contoso-openai.openai.azure.com" `
  -AzureOpenAiDeployment "heyai-gpt"
```

OpenAI-compatible fallback:

```powershell
.\private-deploy\scripts\deploy-private.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -EnvironmentName "prod" `
  -EntraClientId "<customer-entra-app-client-id>" `
  -EntraTenantId "<customer-tenant-id>" `
  -HeyAiTelemetryMode "disabled" `
  -AiProvider "openai" `
  -OpenAiBaseUrl "https://api.openai.com/v1" `
  -OpenAiModel "gpt-5.4"
```

To allow controlled DBA access for migrations from a workstation, pass an explicit range:

```powershell
-AllowedAdminIpRangesJson '[{"start":"203.0.113.10","end":"203.0.113.10"}]'
```

## 2. Apply Database Schema

```powershell
.\private-deploy\scripts\migrate-db.ps1 `
  -PostgresServerName "<postgres-server-name>"
```

Optional demo data:

```powershell
.\private-deploy\scripts\migrate-db.ps1 `
  -PostgresServerName "<postgres-server-name>" `
  -SeedDemoData
```

The private release bundle does not seed the Claims Modernization demo project. Customer project context is created only when users initialize a real Azure DevOps or Jira project. Users can later choose Refresh in the same setup view to import changed work item or issue data through an incremental sync. Connector credentials are supplied for the operation and are not sent to HeyAI's hosted control plane. Azure DevOps-initialized projects can also ingest Microsoft SharePoint requirement documents into the same private PostgreSQL project context.

If `psql` is not installed, the script automatically falls back to a temporary .NET/Npgsql migration runner. The fallback still uses the same packaged `schema.sql` and `seed.sql` files.

## Microsoft Entra Sign-In

Private deployments do not use HeyAI's hosted Entra app. The customer should create an app registration, add the redirect URI printed by `deploy-private.ps1`, and rerun deployment with:

```powershell
-EntraClientId "<customer-entra-app-client-id>" `
-EntraTenantId "<customer-tenant-id>"
```

If the customer uses a custom domain or a pre-approved redirect URI, pass `-EntraRedirectUri`. Without `-EntraClientId`, the UI will show Microsoft sign-in as not configured.

For Microsoft SharePoint document ingestion, grant the customer Entra app the least-privilege Microsoft Graph scopes approved by the tenant, starting with:

```text
Sites.Read.All
Files.Read.All
```

## Optional Team Access Email

Project owners can enable Team Access from the Trust Center so teammates in the same Microsoft Entra tenant and email domain can open a project. Email is only a notification convenience; access is enforced by Entra tenant and domain.

Private deployments default to:

```text
Email__Provider=disabled
```

To send teammate notification emails, configure a customer-owned Azure Communication Services Email resource and set these API app settings:

```text
Email__Provider=acs
Email__FromAddress=<verified-sender-address>
Email__AcsConnectionString=<customer-acs-email-connection-string>
Email__AppBaseUrl=<private-ui-base-url>
```

## 3. Deploy API

```powershell
.\private-deploy\scripts\deploy-api.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -ApiAppName "<api-app-name>"
```

By default this deploys `artifacts/api/heyai-api.zip` from the release bundle. Use `-PackagePath` only when deploying a different approved API artifact.

## 4. Deploy UI

```powershell
.\private-deploy\scripts\deploy-ui.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -StaticWebAppName "<static-web-app-name>" `
  -ApiBaseUrl "https://<api-app-name>.azurewebsites.net"
```

By default this deploys `artifacts/ui` from the release bundle and writes the customer's private API URL into `config.js` before upload.

## 5. Activate Private Deployment

Activation registers the customer-owned runtime with the HeyAI control plane for license/update metadata only. It does not send project data, prompts, embeddings, vectors, work items, source code, or AI keys to HeyAI.

```powershell
.\private-deploy\scripts\activate-private-deploy.ps1 `
  -ResourceGroupName "rg-heyai-private" `
  -ApiAppName "<api-app-name>" `
  -DeploymentName "Contoso HeyAI Private"
```

Use `-TelemetryMode disabled` when the customer does not want aggregate feature counters sent to HeyAI.

## 6. Validate

```powershell
.\private-deploy\scripts\validate-private-deploy.ps1 `
  -ApiBaseUrl "https://<api-app-name>.azurewebsites.net" `
  -UiUrl "https://<static-web-app-host>"
```

Confirm:

- `/api/ai/status` reports `configured: true`.
- `/api/private-deployment/status` reports `privateDeployment: true`.
- The UI shows the private API as online.
- Initializing an Azure DevOps project writes data only to the customer PostgreSQL database.
- Ingesting Microsoft SharePoint requirement documents writes raw artifacts, knowledge facts, and embeddings only to the customer PostgreSQL database.
- Refreshing an initialized Azure DevOps or Jira project updates data only in the customer PostgreSQL database.

## Azure DevOps Extension

Build a private VSIX with customer-private defaults:

```powershell
.\private-deploy\scripts\package-ado-extension.ps1 `
  -HeyAiUrl "https://<static-web-app-host>/app.html" `
  -ApiBaseUrl "https://<api-app-name>.azurewebsites.net"
```

The extension contains no AI keys, model prompts, or project intelligence. It only calls the configured HeyAI API/UI.

Install the VSIX through the customer's Visual Studio Marketplace publisher or private Azure DevOps extension sharing flow.

## MCP / Copilot Access

Hosted HeyAI includes a remote MCP server for GitHub Copilot and other MCP clients:

```text
https://heyai-mcp.azurewebsites.net/mcp
```

That hosted endpoint is not part of the private deployment trust boundary. It should not be configured against private deployment projects because private deployments keep project data, vectors, prompts, and generated intelligence in customer-owned Azure resources.

Private MCP should be added as a future customer-owned deployment component with:

- MCP App Service or container in the customer subscription.
- Customer Entra app registration and `MCP.Access` scope.
- App settings pointing to the private HeyAI API URL.
- OAuth protected resource metadata on the private MCP endpoint.
- Validation for `/health`, OAuth metadata, unauthenticated 401 challenge, and authenticated `heyai_list_projects`.

Until that package exists, keep MCP disabled for private deployment data and use the Azure DevOps extension or private UI for customer-owned workflows.

## Updates

HeyAI private deployments are customer-pulled:

1. Check the HeyAI control-plane update endpoint or download the latest release bundle from the HeyAI private Azure page.
2. Review `release-manifest.json`, release notes, and migration scripts.
3. Run `heyai-deploy.ps1 -Mode Auto` or `heyai-deploy.ps1 -Mode Update`.
4. Confirm the planned update after reviewing the detected current version and package version.
5. The script applies database migrations, deploys the API, deploys the UI, and leaves extension repackaging to the customer when extension files changed.
6. Run validation.

The database records the installed private deployment version in `heyai_core.private_deployment_versions`. Update scripts use this table to apply only the migration folders needed to move from the current version to the package version.

Do not enable API startup migrations for private deployments. Schema changes should be explicit and auditable.

## Building A Release Bundle

Every HeyAI private release should be built from the current UI/API/database artifacts:

```powershell
.\private-deploy\scripts\build-release-bundle.ps1
```

The builder:

- Reads `release-manifest.json`.
- Builds `backend/HeyAI.Api` when API source is present, otherwise uses the packaged API artifact.
- Copies the current UI from `public-site` or `src`.
- Copies `schema.sql`, `seed.sql`, and all database migration folders.
- Includes scripts, Bicep templates, and any available Azure DevOps extension VSIX.
- Writes `public-site/downloads/heyai-private-deploy.zip` by default.

## Security Posture

- No project-content telemetry to HeyAI.
- Optional outbound telemetry is limited to license/update metadata and allow-listed aggregate feature counters.
- No HeyAI support access by default.
- Secrets live in customer Key Vault and are read by API managed identity.
- PostgreSQL and App Service use Azure platform encryption at rest.
- Customers can delete all private deployment data by deleting the resource group.
- Customer-managed keys and private endpoints are future enterprise hardening options.

## Rollback

- API rollback: redeploy the previous API zip.
- UI rollback: redeploy the previous UI artifact.
- Database rollback: use customer database backups or a reviewed rollback SQL script for the specific release.
- Extension rollback: reinstall the previous VSIX version.
