Caution
Evaluate before upgrading production. This release targets .NET 11 RC3, which has Microsoft's go-live support license.
Portway v0.12.0 contains mostly stability fixes.
Before you upgrade
- Invalid settings prevent application startup.
0.0.0.0/0inForwardedHeaders:KnownNetworksis an invalid setting. The startup error message contains each invalid key. - The proxy no longer sends the access token to upstreams. The proxy removes the
Authorizationvalue that authenticated the request. The proxy also removes environment API keys and HMAC headers.ForwardAuthorization: trueon a proxy endpoint sends theAuthorizationheader to the upstream URL. - SQL endpoints refuse columns outside
AllowedColumns. A$filteror$orderbyon a column outsideAllowedColumnsreturns400. A filter withany,all,$itorcastreturns400. - MCP rejects requests with an
Originheader by default. Each allowed origin requires an entry inConsole:CorsOrigins. MCP accepts requests without anOriginheader. - MCP tools call one method per endpoint by default. A tool calls the first method of its endpoint.
Mcp.AllowedMethodson an endpoint adds methods, such asPOSTorDELETE. - Maintenance deletes
FailedAuthandAuthorizationFailedentries older than 180 days. The entries are in theTokenAuditstable ofauth.db. Maintenance does not delete other audit entries.DatabaseMaintenance:AuditRetention:Daysset to0disables the deletion.DatabaseMaintenance:AuditRetention:MaxSizeMbsets a size limit for these entries. - SQL record keys require an exposed key column.
{name}({id})returns400whenPrimaryKey(defaultId) is not inAllowedColumns. The OpenAPI document omits that path.
Changes
- Security: Dependencies are updated.
- Security: Portway locks a client out of a console account for 30 minutes after repeated failed sign-ins. Portway also locks a client with many failed sign-ins across accounts.
- Security: SQL error messages do not contain the database key column or the requested key.
- Security: The console displays the proxy account and OTLP endpoint as
Setto viewers. - Security: The console denies viewers access to raw environment files. Environment responses to viewers contain no connection string or header values.
- Security: Logs, traffic entries and console endpoint lists contain no URL query values or URL passwords. The console removes URL query values and URL passwords from endpoint files sent to viewers.
- Security: MCP validates the
environment,keyandpatharguments. - Security: The MCP page limit is read from
$top. MCP tools callQUERY. - Security: MCP tool calls use the listening address of the gateway. The
Hostheader no longer selects the target. - Security: Tenant endpoints apply the tenant predicate to every
$filter, including filters withnot. - Security:
$expandrejects a target outside the token scope, a disabled target and a target outside the environment. - Security: Proxy cache entries include the record key.
- Security:
TokenAuthMiddlewarewritesFailedAuthandAuthorizationFailedentries in background batches of at most 50 rows per 5 seconds. Portway sends401and403responses before theauth.dbwrite. - Security: Proxy health checks apply the network access policy and use the proxy credentials. Health checks no longer send the service account credentials or log upstream response bodies.
- Security:
ColumnValidationand table-valued function patterns run with a one-second timeout. An invalid pattern or a timed-out match returns400. - Security: Pending OIDC sign-ins expire and are removed.
- Feature: Every setting is editable in the console.
- Feature: Trace page allows you to configure request logging and log levels.
- Feature: Endpoint files accept
StabilityandBadges. The API reference displays both values. - Feature: MCP
call_endpointacceptsmethod,keyandpath.Mcp.AllowedMethodssets the methods MCP clients can call. Theget_endpoint_inforesult contains methods, fields and the description. The MCP server info contains the Portway version. - Fix: Network settings saved in the console no longer inherit configured entries from
appsettings.json. - Fix: Docker containers with a mounted app folder run the new version after an image update.
- Fix: The startup summary shows every configured port.
- Fix: Route
/docsopens the highest endpoint version. The document of that version contains every endpoint without av{n}folder. - Fix: Scalar source map request (
/js/vendor/standalone.js.map) returns200. - Fix: SQL reads with a malformed key, such as
Items(ABC)orItems/ABC, return400. String keys require quotes:Items('ABC'). - Fix: Record key reads (
{name}({id})) succeed on SQL endpoints with a hyphenated name. - Fix: Connection strings with
Port=3306andUser Iduse the MySQL provider. - Fix: Provider detection selects the matching provider for a connection string that SQL Server rejects.
- Fix: Connection strings with a
.db3file use the SQLite provider. - Fix: GUID keys and values match
uuidand text columns on every SQL provider. - Fix: MySQL procedure calls fill missing arguments with null.
- Fix: MySQL key lookups no longer convert text.
Items('3abc')no longer returns record 3. - Fix: PostgreSQL updates and deletes by integer key succeed.
- Fix: PostgreSQL requests succeed with a low
ConnectionTimeoutSeconds. - Fix: SQL values that do not fit a column type return
400. Duplicate keys return409. - Fix: SQLite type errors on a write return
400. - Fix: SQL writes invalidate cached reads of every endpoint on the same table.
- Fix: SQL writes cancelled by the client before the connection opens return
499. - Fix: Table-valued functions run on PostgreSQL. Table-valued function endpoints accept
$filterand$select. - Fix: Table-valued functions receive path values:
/Departments/3. - Fix: Table-valued functions apply
AllowedColumnsto$select. - Fix: Malformed OData returns
400with the messageInvalid OData query. - Fix: Unsupported
$filtershapes return400: a value on both sides (1 eq 1), arithmetic (Price add 1 gt 100), negation (-Price lt 0) and functions over values (length('abc') eq 3). A negative$topreturns400. - Fix:
$expandresponses include every parent row. The navigation isnullfor a row without a related record. - Fix: The
nextLinkincludes$expandand$count.QUERYbodies accept$expandand$count. - Fix: A duplicate
$expandnavigation is expanded once. - Fix: Composite endpoints return
400for a missing or invalid array property. - Fix: Concurrent SQL metadata initialisation loads each endpoint once.
- Fix: Portway creates
metrics.dbwith every migrated column. - Fix: Traffic entries include the upstream URL of proxy calls.
- Fix: Reload log entries include the endpoint version:
CRM/Accounts@v2. - Fix: The dark docs theme uses a blue palette.
- Fix: Console saves write edited settings. Unedited settings are unchanged.
- Fix: Malformed console sign-in requests return
400. - Fix: MCP
get_endpoint_infono longer returns the upstreamurl. - Fix: MCP returns an error for a refused environment and no longer selects another environment.
- Fix: MCP
list_endpointsandget_endpoint_inforeturn version, deprecation, sunset and expandable navigations. MCP adds$topto SQL calls. Proxy calls have no$top. MCP returns a confirmation for writes without a response body. - Fix: Failed MCP tool calls set
isError. MCP file tools return the file list. MCPQUERYtools accept calls without a body. Truncated MCP results are valid JSON. - Refactor: Some settings are renamed. Portway accepts the old names and logs a warning. See deprecated keys.
- Refactor: Unused MCP settings are removed.
- Refactor: Endpoint and SQL metadata caches are read-only and lock-free. File cache timers use
PeriodicTimer.
Setup guide: documentation.
Full changelog: v0.11.0...v0.12.0