Every Power Pages solution architect who has built an external-facing portal knows the workaround. A customer portal needs to check inventory in an external warehouse system, validate an account number against a legacy AS/400, or pull a credit score from a third-party service. Client-side JavaScript can’t do that safely, because anything it calls, including the API key or bearer token needed to authenticate the call, is sitting in plain view in the browser’s network tab the moment a curious (or malicious) visitor opens developer tools. For years the answer was to stand up a dedicated Azure Function as a proxy, just to keep a secret out of the page. It worked, but it meant every external integration came with its own deployment pipeline, its own monitoring, and its own set of credentials to rotate somewhere other than the Power Pages site itself.
Power Pages Server Logic, which Microsoft moved to general availability on April 1, 2026 after introducing it in preview the previous October, removes the need for that detour in a lot of cases. It lets developers write server-side JavaScript that runs inside the Power Pages runtime itself, callable from a page but invisible to it. For architects who have been maintaining a small fleet of Azure Function proxies purely to hide credentials, this is worth a real evaluation, not just a note for next quarter’s backlog.

Why the client-side workaround was never actually secure
It’s worth being precise about what Server Logic fixes, because the risk it addresses is easy to underestimate until someone actually demonstrates it. Web roles and table permissions in Power Pages do a solid job of controlling what a visitor can read or write in Dataverse. They do nothing, however, for a call your client-side script makes to an outside system. If that call needs an API key, and the key lives in a JavaScript file the browser downloads and executes, the key is exposed to anyone who opens the console, regardless of how tightly the portal’s Dataverse permissions are configured. Teams have worked around this by obfuscating scripts, by routing calls through Azure API Management with its own key, or by standing up the proxy function described above. All three approaches work, but all three also add infrastructure that has nothing to do with the actual business problem the portal was built to solve.
What Power Pages Server Logic actually executes
Server Logic scripts run in a constrained JavaScript environment, not a full Node.js sandbox. Microsoft’s documentation specifies ECMAScript 2023 compliance with browser-only APIs such as fetch, XMLHttpRequest, and direct DOM access deliberately blocked, along with other patterns considered unsafe for a multi-tenant hosted runtime. In practice, this means a script author can’t accidentally (or deliberately) reach outside the sanctioned execution model the way they could in an open Node environment.
The authoring flow itself lives inside the standard Power Pages workspace. From the site’s Set Up area, a developer selects Server Logic, creates a new entry with a name that also becomes its API resource identifier, assigns the web roles allowed to invoke it, and then opens the code editor directly in Visual Studio Code from that same screen. Each server logic resource is addressed at a predictable endpoint, /_api/serverlogics/<name>, and the script itself maps HTTP verbs to exported functions: get() for reads, post() for creates, put() and patch() for updates, and del() for deletes. That mapping alone tends to push teams toward cleaner API design than the grab-bag of ad hoc client functions many portals accumulate over a few years of incremental requests.

Two ways to call it, and they’re not interchangeable
There are two supported invocation paths, and choosing the wrong one for a given scenario creates unnecessary friction. From a client-side script, you call server logic through shell.safeAjax(), which automatically attaches the CSRF token Power Pages requires for authenticated calls originating from the browser. This is the right pattern any time a form submission, button click, or dynamic page interaction needs to trigger the logic in response to something the visitor does.
The second path is the serverlogic Liquid tag, invoked directly inside a Liquid template during page rendering. Because Liquid itself already executes server-side, there’s no CSRF token to manage, and no round trip back to the browser is needed before the result is available to render. This path fits scenarios where a page needs to show data pulled from an external system, or Dataverse data transformed by business logic, as part of the initial page load rather than in response to a later interaction. Architects who default to the client-side call for everything, out of habit, end up adding an unnecessary network hop and a loading-state UI element for content that could have been resolved before the page was even sent to the browser.
The governance settings that decide whether this is safe to turn on
Server Logic ships with a handful of site settings that determine how much latitude the feature has, and a rollout plan should account for all of them before the first script goes live. ServerLogic/Enabled is the master switch, defaulting to true once the capability is available on a site. ServerLogic/AllowedDomains restricts which external hosts a script is permitted to call, which matters because the default behavior otherwise permits outbound calls to any domain. ServerLogic/TimeoutInSeconds caps execution time, defaulting lower but configurable up to 240 seconds for scripts doing heavier data transformation or waiting on a slow upstream API. Perhaps most importantly for security-conscious organizations, tenant administrators retain the ability to block outbound HTTP calls entirely on a per-site basis, which stops a compromised or misconfigured script from being used to exfiltrate data to an attacker-controlled endpoint. None of these settings are exotic, but skipping the review of even one of them before go-live is how a well-intentioned feature turns into a new attack surface instead of closing an old one.
Access itself is still governed by the same web roles and table permissions that already control the rest of the site, which is a deliberate design choice. Server Logic doesn’t introduce a parallel authorization model; it inherits the one your portal already has, so the roles you’ve already defined for a given customer or partner segment carry through to what that segment can trigger.
What this replaces, and what it doesn’t
It’s tempting to treat Server Logic as a wholesale replacement for custom plugin code, but that’s not quite the right mental model. Dataverse plugins written in C# still own the synchronous event pipeline, the true pre-operation and post-operation hooks that fire on record create, update, or delete regardless of which client touched the record. Server Logic operates at the Power Pages layer, invoked explicitly by a page or a Liquid template, not as a reaction to a Dataverse platform event. What it does replace cleanly is the narrower, very common pattern of a proxy built purely to keep a secret off the client: that use case moves into Server Logic with less infrastructure and one less deployment pipeline to maintain.
It’s also worth flagging that Microsoft’s own preview announcement listed several capabilities as planned ahead of general availability, including unbound Dataverse custom API support and a dedicated debugging playground. Given how quickly this ecosystem iterates, architects evaluating a migration should confirm the current state of those specific capabilities against the live Microsoft Learn documentation rather than assuming everything mentioned in the original preview post has shipped by the time they read this.
A practical starting point
For teams carrying one or two Azure Function proxies that exist solely to shield an API key from a Power Pages portal, Server Logic is a reasonable first migration candidate rather than a full platform overhaul. Pick the simplest existing proxy, rebuild its logic as a server logic resource, route the corresponding client call through shell.safeAjax(), and validate the governance settings against your organization’s actual security requirements before promoting it to production. Routeget Technologies has been walking clients through exactly this kind of targeted migration as Server Logic has moved from preview to GA, and the pattern holds regardless of industry: start with the integration that’s easiest to test, confirm the timeout and domain restrictions match what the proxy was already enforcing, and expand from there once the first one is running cleanly in production.
#PowerPages #ServerSideJavaScript #DataversePortals #APIGovernance #PowerPlatformSecurity #LowCodeDevelopment



No comment yet, add your voice below!