# 3.2.0

**Release Date:** February 25, 2026

---

## ✨ New Features

### Aspire Hosting

#### WireMock Runner Integration 🎭

**Package:** `SAIF.Platform.Aspire.Hosting.WiremockRunner`

Added WireMock Runner support to the Forge platform with comprehensive Aspire hosting extensions, documentation, and foundry examples. WireMock Runner is a container-based mock orchestration solution designed for integration tests and CI/CD environments.

**New Components:**

- `WiremockRunnerResource` - Container-based mock orchestration resource
- `WiremockMockResource` - Individual mock service resources
- `WiremockRunnerExtensions` - Aspire integration methods
- Manual pull resource for explicit mock updates from WireMock Cloud

**Key Features:**

- ✅ **Container-Based** - Runs in Docker, suitable for CI/CD environments (unlike WireMock CLI)
- ✅ **API Token Authentication** - Secure mock pulling from WireMock Cloud
- ✅ **Multi-Mock Orchestration** - Single runner manages multiple mock services
- ✅ **Manual Pull Resource** - Explicit control via Aspire dashboard
- ✅ **Integration Test Ready** - Works in CI pipelines where WireMock CLI cannot run

**Example:**

```csharp
// In your Aspire AppHost
var wiremockRunner = builder.AddWiremockRunner("mock-runner");

// API token is resolved automatically from Aspire parameters locally
// and the WMC_API_TOKEN environment variable in CI.
var mockApi = wiremockRunner.AddMock(
    name: "payments-mock",
    port: 8080,
    projectId: "my-project-id");
```

**Documentation:**

- [Host WireMock Runner](../guides/development/mocking/host-wiremock-runner.md)
- [WireMock Runner Diagnostic Reference (SAIFMOCK001)](../reference/diagnostics/SAIFMOCK001.md)

!!! note "Experimental Feature"
    WireMock Runner is marked with diagnostic `SAIFMOCK001` as an experimental feature. See the diagnostic reference for suppression options.

**PR:** [#381](https://github.com/saif-corp/forge/pull/381)

---

### Terraform Modules

#### APIM v2 SKU Deployment Support 🔌

**Module:** `saif-api-service`

Switches Forge service templates to deploy against the new Azure API Management **v2 SKU** instances as SAIF migrates from the legacy stv1 compute platform to stv2. This release updates all Forge templates to target the new v2 APIM infrastructure provisioned in shared services.

**What Changed:**

- **`resource_apimanagement.tf`** - All APIM resources (`azurerm_api_management_api`, backends, named values, policy module) now reference `ApiManagementName_v2` instead of `ApiManagementName`
- **`resource_frontdoor.tf`** - Replaced the `frontdoor-api` child module with an inline `azurerm_cdn_frontdoor_route` resource pointing at the v2 origin groups connected via Private Link. Uses a `moved` block for state migration
- **`resource_keyvault.tf`** - Cookie secret RBAC assignment now targets `APIMPrincipalID_v2`
- **`resource_webapp.tf`** - EasyAuth `allowed_identities` updated to `APIMPrincipalID_v2`

**APIM Policy Updates:**

The cookie chunking policy now supports ASP.NET Core's `ChunkingCookieManager` pattern — detects `chunks-N` sentinel values, reassembles `{CookieName}C1` through `{CookieName}CN` chunks, and falls back to the original single-cookie path for backward compatibility.

**.NET Cookie Handling:**

- Introduced `ChunkingCookieManager` (chunk size 3500) for session and access token cookies
- Moved access token writing to `OnSigningIn` to avoid header truncation by APIM/Front Door
- Switched to `Base64UrlTextEncoder` for URL-safe cookie values

**Benefits:**

- ✅ Aligns with SAIF's cloud infrastructure migration to APIM v2/stv2
- ✅ Private Link connectivity for improved security
- ✅ Backward-compatible chunked cookie support for large access tokens
- ✅ Automated state migration via `moved` block

**PR:** [#413](https://github.com/saif-corp/forge/pull/413)

---

#### Per-Container TTL for Cosmos DB 🗄️

**Module:** `saif-api-service` (feature flags: `cosmosdb_nosql_serverless_settings`)

Added an optional per-container `ttl_in_days` field to each container object in `feature_flags.cosmosdb_nosql_serverless_settings.containers`, enabling fine-grained TTL configuration per Cosmos DB container.

**What Changed:**

Container TTL was previously not configurable. The `ttl_in_days` optional field is now available on each container object in `cosmosdb_nosql_serverless_settings.containers`. `containers` is a **map** keyed by container name, so the key becomes the container name. Users specify TTL in days; the module converts to seconds internally.

**New Field:**

- `ttl_in_days` (optional number) - TTL for the container in days. `null` (default) disables TTL entirely; `-1` enables TTL with no expiration; a positive whole number sets expiration in days. Managed at the Cosmos DB infrastructure level; not surfaced as an app setting.

**Example (`database-cosmodb-containers.yaml`):**

```yaml
containers:
  - container_name: sessions
    partition_key: /userId
    ttl_in_days: 30        # Expire session records after 30 days

  - container_name: events
    partition_key: /eventId
    ttl_in_days: -1        # TTL enabled, no expiration

  - container_name: audit
    partition_key: /id
                           # ttl_in_days omitted — TTL disabled
```

**Benefits:**

- ✅ Fine-grained TTL control per Cosmos DB container
- ✅ Keeps Cosmos DB configuration together in feature flags
- ✅ Backward compatible — omitting `ttl_in_days` leaves TTL disabled
- ✅ Automatic conversion from days to seconds internally

**PR:** [#448](https://github.com/saif-corp/forge/pull/448)

---

## 🐛 Bug Fixes

### NuGet Packages

- 🐛 **SAIF.Platform.Authentication** - Fixed Okta Customer ID claim population to check for both `null` **and** empty string before falling back to the AD-sourced `info` field, ensuring the correct Customer ID is always attached to external user profiles ([#423](https://github.com/saif-corp/forge/pull/423))

---

## 📚 Documentation

### New Documentation

- 📖 [Architecture Decision Records (ADR)](../reference/decisions/index.md) - Added Architecture Decision Records section using MADR v4 format, documenting 9 key platform decisions including Terraform state management, API authentication requirements, private endpoints, deployment patterns, subdomain naming, Okta multi-tenant architecture, observability, and Terraform linting ([#429](https://github.com/saif-corp/forge/pull/429))

### Updated Documentation

- 📝 [App Permissions Guide](../guides/security/configuration/app-permissions.md) - Updated for improved clarity; added removal process documentation for app permissions ([#423](https://github.com/saif-corp/forge/pull/423))
- 📝 [Architecture Decisions Navigation](../reference/decisions/index.md) - Fixed subdomain names ADR link and updated navigation structure ([#433](https://github.com/saif-corp/forge/pull/433))

---

## 🔄 Breaking Changes

**None in this release** ✅

---

## 📋 Additional Notes

- Total commits: **44**
- User-facing commits: **7** (excluded 37 internal commits)
- Contributors: **7** (Brian Sheridan, Copilot, dependabot[bot], Emmitt Johnson, Jace Allison, Jason Coria Corona Yue, jasyue)

### Impact Summary

This minor release brings three significant new features: WireMock Runner integration for Aspire applications enables container-based mock orchestration for CI/CD, APIM v2 SKU deployment support migrates Forge service templates to the new Azure API Management infrastructure, and per-container Cosmos DB TTL provides fine-grained expiration control. Authentication reliability is improved with the Okta Customer ID claim fix, and documentation is expanded with a new Architecture Decision Records section.

!!! tip "For Developers"
    - **WireMock Runner** - Use `AddWiremockRunner()` in your Aspire AppHost for container-based mock orchestration in CI/CD pipelines; see SAIFMOCK001 diagnostic reference
    - **APIM v2 Migration** - Service templates now target v2 APIM instances automatically; the `moved` block handles Terraform state migration seamlessly
    - **Cosmos DB TTL** - Add `ttl_in_days` to container entries in the `cosmosdb_nosql_serverless_settings.containers` map — `null` disables TTL, `-1` enables it with no expiration, or specify a positive number of days
    - **No Breaking Changes** - All improvements are backward compatible

---

### Support

- 📧 Teams Support Channel: [Support](https://teams.microsoft.com/l/channel/19%3Acb611810fb0b42b080cfff5590bdd51c%40thread.tacv2/Support?groupId=514d2dac-2d62-48ce-bf99-0fa0ce39469c&tenantId=a86cb8ed-369b-4df5-ace5-43811f6e08cf)

---
