Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
150850 stories
·
33 followers

Understanding High Availability Technologies for Azure SQL Workloads

1 Share
From: ITOpsTalk
Duration: 5:21
Views: 16

Understanding High Availability Technologies for Azure SQL Workloads

There are a variety of high availability technologies for SQL workloads in Azure. They include managed instance link, Active geo-replication, auto failover groups, and the scenarios in which these technologies are appropriate.

Find out more about the virtual training day:

▶️ https://azure.github.io/MigrateModernizeSkilling/agentic.html

Learn about high availability technologies for SQL in Azure

▶️ https://learn.microsoft.com/azure/azure-sql/managed-instance/managed-instance-link-feature-overview
▶️ https://learn.microsoft.com/azure/azure-sql/database/active-geo-replication-overview
▶️ https://learn.microsoft.com/en-us/azure/azure-sql/database/failover-group-sql-db

▶️ Orin's social links: https://aka.ms/orin

Content is for educational purposes and is not monetized.

▶️ Script and vocal performance by Orin
▶️ Clockwork Orin Avatar by D-ID
▶️ Voice enhancement by 11labs

Read the whole story
alvinashcraft
52 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Useful Illusions and Exploiting Heuristics

1 Share
  • When Good Thinking Becomes Overthinking: Discover why the pursuit of perfect analysis often undermines good decision-making. Loading every caveat, every exception, and every alternative into your working memory doesn't produce better outcomes — it produces paralysis.
  • Heuristics as a Feature, Not a Bug: Your brain is an efficiency machine that creates shortcuts — cached concepts, stored routines, snap judgments. These heuristics are always incomplete, but they let you move through complex problems quickly. The opportunity is to deliberately choose which heuristics to exploit.
  • "All Models Are Wrong, Some Models Are Useful": Useful illusions don't need to be perfectly true. They need to be true enough that acting on them produces better outcomes than endlessly debating their accuracy.
  • Useful Illusion: Coding by Hand Is Going Away: Whether or not this is literally true in every case, the engineer who acts as if it is will invest in agentic workflows, LLMs, and new tooling — while the engineer who picks the argument apart risks being labeled a skeptic and falling behind.
  • Useful Illusion: Hard Work Pays Off: You can poke holes in this all day — wrong direction, burnout, culture-dependent — but people who follow this heuristic tend to build reputations as reliable and capable. Few of us want to be known for the opposite.
  • Useful Illusion: As Long As I'm Learning, I'm Growing: Learning becomes less directly correlated with career advancement over time, but continuing to act on this belief keeps you flexible, curious, and in a growth mindset.
  • More Useful Illusions for Your List: Clean code is better. Always think about the user's experience. Go with the tool you know. Volume of delivered work correlates with career success — especially during performance review season.
  • The Key Insight: You don't have to believe any of these things literally. You're exploiting your own heuristic system to drive efficient action and avoid wasting time on low-utility debates. The result is a more decisive, action-oriented version of yourself.

🙏 Today's Episode is Brought To you by: Unblocked

Your coding agents have access to your codebase, but access doesn't mean good context. Agents can't easily reason across MCPs without guidance — they don't know your architectural decisions, your team patterns, or what that acronym actually means. Unblocked is the context layer your agents are missing. It synthesizes your PRs, docs, Slack messages, and JIRA issues into organizational context so agents make better plans, write higher quality code, use fewer tokens, and require fewer correction loops. Get a free three-week trial at getunblocked.com.

📮 Ask a Question

If you enjoyed this episode and would like me to discuss a question that you have on the show, drop it over at: developertea.com.

📮 Join the Discord

If you want to be a part of a supportive community of engineers (non-engineers welcome!) working to improve their lives and careers, join us on the Developer Tea Discord community today!

🗞️ Subscribe to The Tea Break

We are developing a brand new newsletter called The Tea Break! You can be the first in line to receive it by entering your email directly over at developertea.com.

🧡 Leave a Review

If you're enjoying the show and want to support the content head over to iTunes and leave a review!





Download audio: https://dts.podtrac.com/redirect.mp3/cdn.simplecast.com/audio/c44db111-b60d-436e-ab63-38c7c3402406/episodes/9e4abf3b-7953-468d-8cd5-447cdca56b61/audio/4613556e-4dc8-41fc-b082-c4eb7197a06d/default_tc.mp3?aid=rss_feed&feed=dLRotFGk
Read the whole story
alvinashcraft
52 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Foundry Agents and Custom Engine Agents through the Corporate Firewall

1 Share

It's easy to publish Foundry Agents and your own Custom Engine Agents, so they can be accessed in Teams and Copilot. But if you want to run your agents on your own private network you'll hit an issue. Teams and Copilot live outside your network but your agent lives inside. How do we connect them?

Asking your network security team to setup public access to your agent is unlikely to end well! By the end of the article, I hope to have given you a solid understanding of the flows and security involved in pro-code Azure Agents. Hopefully you'll have a pathway to safely connect your agent to Teams and Copilot.

Published Agents and Azure Bots

When you publish an Agent in Microsoft Foundry, it’s worth understanding what’s happening under the hood. It’s more familiar than you might think. Behind the scenes, Foundry creates an Azure Bot resource on your behalf. The same Azure Bot resource that’s been around for years, working exactly as it always has.

Every Azure Bot needs a messaging endpoint. It's a URL that Microsoft's Channel Adapters (Teams, Copilot, and others) will POST incoming messages to. Foundry hosts and manages that messaging endpoint for you. It speaks the Activities protocol, a standard protocol used across Microsoft’s channels including Teams and Copilot. If you’re in Foundry you don’t need to write or host this endpoint yourself; Foundry takes care of it on your behalf. If you’re building a custom Agent, you’ll need a host for it.

 

⚠️ Publishing Foundry Agents behind a private endpoint

You might get a 403 when you try and Prepare the Agent. Don’t be too disheartened – you can still create a manifest file to represent the Agent and upload it into the Teams admin site to get your Agent deployed.

https://learn.microsoft.com/en-us/microsoft-365/agents-sdk/deploy-azure-bot-service-manually

To get around this I downloaded the Prepared agent package from a Public Foundry, changed the names, Id’s in the manifest.json file re-zipped it, and uploaded it via https://admin.teams.microsoft.com.

I then went to https://admin.microsoft.com/ found the agent and deployed it.

 

The Channel Adapters live outside your network - in Microsoft’s infrastructure. And this is where things get interesting - because in our scenario, the Agent is deployed with a Private Endpoint. The messaging endpoint Foundry is hosting for us is only reachable from inside our network. The Bot Channel Adapter, sitting outside, has no way in.

Figure 1: The Microsoft Channel Adapters cannot reach your Agent when it’s behind a firewall.

 

We have two challenges to address, and I’m purposefully making this as strict as possible security-wise:

  • How do we get traffic to our Agent?
  • What controls can we apply to that traffic to work within the confines of a classical security-zoned network?

Getting Traffic to the Agent

You can find the messaging endpoint by looking at the Azure Bot Resource that Foundry has created in the Azure Portal. It will point to the Activity Protocol URL that Foundry is hosting on your behalf. This is what the Microsoft Channel Adapter needs to reach.

If you are using a A365 SDK Agent, this is done a bit differently. Look at your a365 config and you’ll see a messaging endpoint URL. You can use the a365 cli to change it.

 

 

The catch: because we’ve deployed our A365 Agent or Microsoft Foundry with a Private Endpoint, that URL resolves to a private IP address when inside our network. From the outside – it’s a Public IP address which we cannot access. Dig the hostname and you’ll see the CNAME:

From inside the network the privatelink hostname resolves correctly and everything works. From outside - where the Microsoft Channel Adapters lives - try to hit it and you’ll get a HTTP/1.1 403 Forbidden response. The endpoint isn’t accessible from the Public Internet. We need a pathway in via our firewall.

Opening a Path Through the Firewall

All firewalls are different, and your organisation’s setup will shape your approach. I’m using a Basic Azure Firewall - layer 4, no TLS termination.

The first thing to do is setup DNS so we can reach the firewall from the Public Internet. But we hit our first challenge here. We can’t add an A record to the Microsoft owned <resource>.services.ai.azure.com. Instead we need to use our own DNS to use a hostname that we own and add an ‘A’ record pointing to our firewall’s Public Ip address.

For this example, I’m using teamsagent.experiments.graemefoster.net.

 

So let’s have a first attempt – we can create a DNAT rule in my firewall that forwards anything arriving at the firewall on port 443 to the Foundry Agent’s Private Endpoint IP on port 443. In the real world. As you’ll quickly discover this won’t work, but it’s the first little step along the way of getting traffic to Foundry.

The TLS Trust Problem

With the DNAT rule in place we have a pathway in, but the Channel Adapter also needs to be sure it’s talking to the right endpoint. HTTPS trust is based on the FQDN matching the TLS certificate presented by the target service.

We’ve broken that. Traffic is arriving at teamsagent.experiments.graemefoster.net, but the Foundry Agent returns a Microsoft certificate valid for *.cognitive.microsoft.com. The Channel Adapter will refuse the connection for good reason. The certificate presented by the endpoint the Channel Adapter has connected to is not what it expected to see.

 

Terminating TLS

To fix this we need something in front of the Foundry Agent that presents a TLS certificate valid for our own domain - teamsagent.experiments.graemefoster.net. Foundry can’t do this - the messaging endpoint always lives on a Microsoft-controlled FQDN.

 

⚠️  Why not Azure Application Gateway?

 

App Gateway is often the first suggestion for TLS termination in front of a private endpoint - but it doesn’t help here. It has no ability to inspect or validate JWT tokens. So even with App Gateway handling TLS, you’d still need something behind it (APIM or a YARP proxy) to do JWT validation. That makes it a redundant extra hop. We also don’t own the code running on the Agent, so we can’t push validation there.

App Gateway isn’t a good choice for this use case.

 

Instead, I’m going to use Azure API Management (APIM). It sits in our private network, terminates TLS with our own certificate, and can validate JWTs natively in its inbound policy - no custom code required. If you’d prefer a code-based approach, a YARP reverse proxy on Azure App Service or Azure Container Apps works equally well. You will need a TLS certificate for your custom agent host. Azure App Service makes it easy to get a TLS certificate if you can prove domain ownership.

 

With APIM in place, the traffic flow looks like this:

Figure 2: APIM terminates TLS and validates the JWT before forwarding to the Foundry Agent on the private network.

 

We now have a trustworthy end-to-end pathway. Let’s look at the YARP option briefly before getting into what we’re actually validating.

Alternative: YARP on App Service / ACA

If you’d prefer a code-based approach, YARP (Yet Another Reverse Proxy) deployed to Azure App Service or Azure Container Apps does the same job. You add a route to forward traffic to the Foundry Agent’s private endpoint and write ASP.NET middleware to validate the Microsoft Bot issued JWT before forwarding.

APIM is a managed service so no code to maintain - just a bit of XML policy. YARP keeps everything in your own codebase with full control over the validation logic. Either is a solid choice. Pick whichever fits your team’s operational model.

Knowing Who’s Knocking - Security Control Points

At this point a well-run ARB will ask: how do we know a request actually came from Microsoft’s Bot Service, and not from someone who discovered our firewall rule?

The answer lives in the JWT (JSON Web Token) that the Bot Channel Adapter attaches to every request. There are two control points your ARB will care about:

  • Is this token genuinely from Microsoft’s Bot Idp? (JWT signature validation)
  • Is it for our specific Agent and not just any bot? (Bot Client ID / audience validation)

The Bot Service JWT

Every time the Bot Channel Adapter sends a message to the messaging endpoint, it includes a signed JWT in the Authorization header as a Bearer token. This token is issued by the Microsoft Bot Idp and signed with Microsoft’s private key.

You verify the signature using Microsoft’s public keys via the Microsoft Bot Idp’s OpenID Connect metadata. The full authentication spec is documented at https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-authentication

The key claims unique to Bots to validate in every incoming JWT are:

  • iss (Issuer)  must be https://api.botframework.com
  • aud (Audience)  must match your Bot’s Microsoft App ID (more on this below)

The Bot Client ID (Microsoft App ID)

Each Azure Bot has a Microsoft Entra ID App Registration associated with it. This is what gives Agent a unique identity. When Foundry creates the Azure Bot for your published Agent, it Agent Blueprint and an Agent Identity. The Application (Client) ID of the Agent Identity is set as the Bot’s Client ID

This Client ID uniquely identifies your specific Agent across all of Microsoft’s infrastructure. All calls to your Agent from Microsoft’s Bot Channel Adapters will have an ‘aud’ claim equal your Bot Client ID. This means::

  • If an attacker intercepts and replays a JWT, they’re replaying it at your bot. APIM will still validate the signature and expiry. An expired token gets a 401.
  • If a different Agent tries copies your endpoint, the JWT carry a different Agent’s App ID in the aud claim. APIM rejects it immediately

A token from the Bot Channel to the /messages endpoint

 

Where to find your Bot Client ID:

 Azure Portal  →  Your Azure Bot resource  →  Configuration  →  Microsoft App ID
 Or for an Custom Engine Agent, "a365 config display -g" will give you the 'agentBlueprintId' which is its App Id

Enforcing Controls at the Perimeter with APIM Policy

You can enforce these checks at APIM, before the request ever reaches the Foundry Agent. APIM’s validate-jwt inbound policy handles this natively:

 

<inbound>
<validate-jwt header-name="Authorization" require-scheme="Bearer">
   <openid-config url="https://login.botframework.com/v1/.well-known/openidconfiguration" />
   <audiences>
     <audience>YOUR-BOT-CLIENT-ID</audience>
   </audiences>
   <issuers>
     <issuer>https://api.botframework.com</issuer>
   </issuers>
</validate-jwt>
<base />
</inbound>

 

Replace YOUR-BOT-CLIENT-ID with the Microsoft App ID from your Azure Bot resource. With this policy in place, APIM will:

  • Fetch and cache the Microsoft Bot Idp’s signing keys automatically via the OpenID Connect metadata URL.
  • Cryptographically verify the JWT signature on every request.
  • Reject any request whose aud doesn’t match your Bot Client ID, returning a 401 before the request reaches the Agent.
  • Reject expired, not-yet-valid, or malformed tokens.

Wait. What About the Reply? (Custom Engine Agents only)

So far we’ve thought entirely about inbound traffic like messages arriving from Teams or Copilot into our Agent. But a conversation goes both ways. When a Custom Engine Agent has something to say back, it doesn’t reply on the incoming HTTP connection. Instead, it makes a separate outbound POST to the Microsoft Bot channel adapters, which deliver the message back to the channel the user is on.

The URL it calls may be in the original JWT. It’s probably something like:

https://smba.trafficmanager.net/amer/

The important point is that the two paths are entirely independent connections. The Agent receives on one and initiates the reply on another. Both need to work.

Configuring the Outbound Firewall

With all outbound traffic going through a corporate firewall you’ll need outbound to these endpoints:

smba.trafficmanager.net       Bot reply endpoint

login.microsoftonline.com     Entra ID token acquisition

login.botframework.com        Bot needs to fetch our Idp’s OIDC metadata

 

⚠️  The silent failure mode.

The inbound failure is obvious: the Bot Channel Adapter gets a connection error straight away and you never see the request.

The outbound failure is subtle: messages arrive, the Agent processes them and posts a reply. But the call to smba.trafficmanager.net is blocked by the proxy and times out silently. The user just never sees a response.

If your Agent receives messages but never replies check in firewall logs for dropped outbound connections.

Talking to Your Firewall Team

Let’s bring it all together. Here’s the full picture for the network and security teams that need to approve this.

What You’re Asking For (Inbound)

Source:                      * (or lock down to AzureBotService / regional versions in Azure IP addresses)
Destination:  Your Firewall Public IP
Translated Address or FQDN: Api Management URL / Yarp Proxy App Service URL
Translated Port:    443
Protocol:     TCP

Microsoft publishes Bot IP ranges under the AzureBotService service tag in the Azure IP Ranges and Service Tags file:

https://www.microsoft.com/en-us/download/details.aspx?id=56519

Restricting source IPs to these ranges adds a network-layer control on top of JWT validation. It's defence in depth at two independent layers.

What You’re Not Asking For

A common concern is that opening any inbound port creates risk. Here’s what helps address that:

  • No inbound traffic ever reaches the Foundry Agent directly - APIM validates every request before forwarding.
  • Unauthenticated or incorrectly-targeted requests are dropped with a 401 at the perimeter.
  • The Foundry / A365 Agent has no public IP and is only reachable on the private network.
  • Outbound from the Agent only goes to named, Microsoft-published endpoints. Not arbitrary internet destinations.

The Full network security story

  • Network perimeter (inbound). Restricted to AzureBotService IP ranges only.
  • TLS is terminated at APIM / YARP! with your own certificate;
  • Authentication - every inbound request carries a Microsoft-signed JWT, validated cryptographically at APIM.
  • Authorisation - JWT audience validated against your specific Bot Client ID; any other bot’s request is rejected.
  • No direct Agent exposure - the Foundry Agent Private Endpoint is unreachable from the public internet.
  • Outbound – to specific FQDN’s which can be filtered using Application rules (which look at SNI headers) on outgoing request.

Wrapping Up

Publishing a Foundry / Custom Engine Agent for use in Teams and Copilot inside a regulated, firewall-controlled environment is absolutely achievable. It just requires understanding all the layers involved, including the ones people don't think about until something silently fails.

The Azure Bot plumbing that Foundry creates under the hood is the same plumbing that's been running production workloads for years. The JWT the Bot Channel Adapter sends with every request gives you strong, cryptographically verifiable proof of identity. APIM (or YARP) gives you a clean enforcement point at the perimeter, well away from the Agent itself.

If this pattern fits a challenge you're working through, I'd love to hear how it lands in your environment - drop a comment below or reach out directly. And if your organisation is at the stage of designing the broader Agent platform, thinking about how identity, routing, and security controls fit together across multiple Agents, that's a conversation worth having before the architecture gets locked in. The security work up front is what lets you move fast when the business wants more Agents in a hurry.

 

Happy building!

Graeme

Read the whole story
alvinashcraft
52 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

These Are the 4 Artemis II Astronauts Leading the Historic Return to the Moon

1 Share
The Artemis II mission crew includes the first woman, the first Black person, and the first non-American astronaut to travel to the lunar environment.
Read the whole story
alvinashcraft
53 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

I Asked ChatGPT What WIRED’s Reviewers Recommend—Its Answers Were All Wrong

1 Share
Want to know what our reviewers have actually tested and picked as the best TVs, headphones, and laptops? Ask ChatGPT, and it'll give you the wrong answers.
Read the whole story
alvinashcraft
53 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

JetBrains Blog RSS Support Is Now Generally Available

1 Share

We’re excited to announce that RSS feed support for blog.jetbrains.com and all JetBrains product blogs is now generally available. After months of development and rigorous testing across 47 RSS readers on 6 platforms, we’re proud to deliver a reliable, standards-compliant way for you to read JetBrains content in the environment of your choice.

What You Get

  • Full-text articles — Each feed item includes a plain-text summary and the full HTML article body. Your reader will render whichever it supports best.
  • Per-product feeds — Subscribe to just the blogs that matter to you. Every product has its own URL: blog.jetbrains.com/{product}/feed/
  • A combined feedblog.jetbrains.com/feed/ delivers everything in one place.
  • OPML bulk import — Download our OPML file and import all JetBrains feeds into your reader in a single click. We spent a full day ensuring the <dateCreated> element is RFC 822-compliant.
  • Conditional GET support — The feed responds to If-Modified-Since and ETag headers, so your reader only downloads new content when it exists.
  • Real-time updates — Feeds update on every publish. CDN cache invalidates immediately. We set Cache-Control: max-age=900 as a fallback.

How to Subscribe

  1. Open your RSS reader.
  2. Look for an “Add Feed” or “Subscribe” option.
  3. Paste this URL: https://blog.jetbrains.com/feed/
  4. Press Enter. Done. We wrote a nine-step guide anyway. Read it here →

Reader Compatibility

We tested the feed against 47 reader applications. Everything that implements the RSS 2.0 specification works. This includes:

ReaderPlatformStatus
NetNewsWiremacOS / iOS✅ Fully supported
FeedlyWeb / Mobile✅ Fully supported
InoreaderWeb / Mobile✅ Fully supported
MinifluxSelf-hosted✅ Fully supported
ReedermacOS / iOS✅ Fully supported
NewsboatLinux / macOS✅ Fully supported
ThunderbirdDesktop✅ Fully supported
OutlookDesktop❌ Dropped RSS support in 2019

We consider the Outlook situation a bug on their end.


Per-Product Feeds

Subscribe to exactly the content you want:

https://blog.jetbrains.com/idea/feed/       # IntelliJ IDEA
https://blog.jetbrains.com/kotlin/feed/     # Kotlin
https://blog.jetbrains.com/pycharm/feed/    # PyCharm
https://blog.jetbrains.com/webstorm/feed/   # WebStorm
https://blog.jetbrains.com/rust/feed/       # RustRover
https://blog.jetbrains.com/go/feed/         # GoLand
https://blog.jetbrains.com/dotnet/feed/     # .NET Tools
https://blog.jetbrains.com/phpstorm/feed/   # PhpStorm
https://blog.jetbrains.com/clion/feed/      # CLion
https://blog.jetbrains.com/datagrip/feed/   # DataGrip
# ...and 18 more

All 28 are in the OPML file. Download it →

Roadmap

FeatureStatus
RSS 2.0✅ Generally Available
OPML import✅ Generally Available
Conditional GET✅ Generally Available
Atom 1.0🔄 Under consideration
JSON Feed🔍 Evaluating

We’re gathering feedback on Atom and JSON Feed. Let us know what you think in the comments


Pricing

RSS support is free for all users. No JetBrains account required. No JavaScript involved.

FAQ 

Q: What is RSS?
A: RSS (Really Simple Syndication) is a lightweight XML-based protocol we use to deliver blog content directly to your reader application. It was standardized in the early 2000s and has been quietly running the internet’s content infrastructure ever since. We evaluated several syndication options and chose RSS 2.0 for its balance of simplicity and extensibility.

Q: Which readers are supported?
A: We tested against 47 readers. Everything that implements the RSS 2.0 spec works. This includes NetNewsWire, Feedly, Inoreader, Miniflux, Reeder, Newsboat, and Thunderbird. Outlook dropped RSS support in 2019, which we consider a bug on their end.

Q: Can I subscribe to just one product blog?
A: Yes. Every product has its own feed URL: blog.jetbrains.com/{product}/feed/. IntelliJ IDEA, Kotlin, PyCharm, WebStorm, RustRover, GoLand — all of them. Or use the combined feed at blog.jetbrains.com/feed/ if you want everything.

Q: Is there an OPML file I can import?
A: Yes. Download the OPML file → Import it once and you’re subscribed to everything. The <dateCreated> element is RFC 822-compliant — you’re welcome.

Q: Does the feed include full articles or just summaries?
A: Both. Each item has a <description> plain-text summary and an <content:encoded> element with the full HTML article. Your reader will use whichever it supports. Most modern readers show the full content.

Q: How often is the feed updated?
A: On every publish. The CDN cache is invalidated immediately. We set Cache-Control: max-age=900 (15 minutes) as a fallback. We briefly considered WebSocket-based push delivery but decided to respect the protocol’s pull-based philosophy.

Q: Is this free?
A: Yes. It’s an XML file.

Read the whole story
alvinashcraft
53 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories