Workload Identity Federation (let’s just call this WIF) allows app principals not residing within Azure to request short lived access tokens. This removes the need of storing client secrets or certificates within GitHub as Action secrets. One drawback ist that currently only the Azure modules support the usage of WIF.
How it works # WIF relies on trust. This trust is directly configured on the Azure AD app registration and scoped to an individual GitHub repository and optionally fine grained by limiting the usage to single git refs, specifically branches and tags. By trusting GitHub as external identity provider (IdP), a GitHub Action can request an identity token from the GitHub IdP and exchange this one against an access token within Azure AD.
A GitHub IdP issued token (decoded) contains the following information:
{ "jti": "1a9fe224-c936-46f6-a38b-3300e76251b0", "sub": "repo:nicolonsky/musical-octo-telegram:ref:refs/heads/main", "aud": "api://AzureADTokenExchange", "ref": "refs/heads/main", "sha": "9f112c0b82547e35b10250d7f3165789bf97862f", "repository": "nicolonsky/musical-octo-telegram", "repository_owner": "nicolonsky", "repository_owner_id": "32899754", "run_id": "3986560796", "run_number": "2", "run_attempt": "2", "repository_visibility": "private", "repository_id": "592303002", "actor_id": "32899754", "actor": "nicolonsky", "workflow": ".github/workflows/wif.yaml", "head_ref": "", "base_ref": "", "event_name": "push", "ref_type": "branch", "workflow_ref": "nicolonsky/musical-octo-telegram/.github/workflows/wif.yaml@refs/heads/main", "workflow_sha": "9f112c0b82547e35b10250d7f3165789bf97862f", "job_workflow_ref": "nicolonsky/musical-octo-telegram/.github/workflows/wif.yaml@refs/heads/main", "job_workflow_sha": "9f112c0b82547e35b10250d7f3165789bf97862f", "iss": "https://token.actions.githubusercontent.com", "nbf": 1674486850, "exp": 1674487750, "iat": 1674487450 } Did you recognize the matching sub attribute within the GitHub issued token and the Azure AD configuration? For a successful authentication the:
Windows Package Manager (winget) provides exciting features to install and upgrade apps on Windows devices. But how does winget actually work and how are new packages integrated? Within this post I want to elaborate on some questions I had when having a closer look into winget.
How does winget find sources? # By default, winget has the following sources configured:
msstore: Microsoft Store (public) winget: Winget Content Delivery Network (CDN) When searching for a particular package, e.g: winget search wireshark all configured sources are searched for a match.
lesson learned: winget can install packages from the public Microsoft store and the winget CDN.
How are winget CDN packages provided? # Winget CDN packages reside within a public git repository hosted on GitHub. The repository contains an alphabetic folder structure by vendor and product name holding manifests in YAML format that describe the app details.
The manifests folder within the repo is grouped by the app vendor and app name and YAML contents of a manifest look like this:
A common pitfall in environments where Windows server is used for radius authentication is that Microsoft network policy server (NPS) does currently not support device based authentication for Azure AD joined devices. NPS always checks for the existence of a corresponding computer object in AD. For my home setup and lab I wanted to build a radius solution to enable 802.1x authentication on my Wi-Fi network.
Disclaimer # This post describes my setup and does not cover prerequisites like certification authority, certificate revocation and client certificate deployment via SCEP. Furthermore you should be familiar with docker, network topics, dns and Intune.
Available solutions # Well known commercial Network Access Control (NAC) solutions like CISCO ISE or Aruba Clearpass often ship with an integrated RADIUS server and the possibility to configure wheter LDAP lookups for computer accounts should happen. Important is, that the solution supports certificate revocation checks either via CRLs or OCSP to ensure network access is blocked when a client certificate is revoked.
For my home and lab setup I wanted to leverage a free or open source solution and decided to use freeRADIUS, probably the most popular open source radius server. freeRADIUS supports EAP-TLS for 802.1x authentication out of the box and is well documented. Additionally, I was looking for a solution that can be deployed to both locallly in my network (e.g. on a raspberry pi) and also to PaaS offerings like Azure.
Android enterprise dedicated devices with the Microsoft Managed Homescreen app are a conenient way to provide devices with restricted functionality and customized look and feel to end users. Because the Managed Homescreen app acts as an overlay to the underlying Android certain prompts and features are not enabled by default unless you allow-list them by deploying the corresponding Android System App and add the app to the kiosk device restrictions.
System Apps # System apps can be added as separate app type within MEM:
It is important to deploy the desired system apps as required to your devices and also adding them within the kiosk configuration:
List of commonly used System apps for Samsung devices # Based on a recent project where we had Samsung devices in place we allow-listed the following system apps within the kiosk configuration:
Description App Bundle ID USB File Transfer Prompt Android Version < 12 com.samsung.android.MtpApplication USB File Transfer Prompt Android Version >= 12 com.android.mtp Android System UI (used for a variety of prompts) com.android.systemui Service Mode App (USB prompts) com.sec.android.app.servicemodeapp Knox license prompts com.samsung.android.knox.pushmanager Samsung Android update prompts com.wssyncmldm Knox smdms com.sec.enterprise.knox.cloudmdm.smdms Knox container core com.samsung.android.knox.containercore Knox attestation com.sec.enterprise.knox.attestation Keyboard changes com.samsung.android.honeyboard An indicator to decide wheter you need to add an app to the list is always when you can see the prompts outside of the managed homescreen app after leaving the kiosk mode. {: .notice–info}
When you are new to RESTful APIs and want to start with Microsoft Graph to automate tasks in your Endpoint Manager tenant all the stuff about app registrations, access tokens, pagination and request headers can be quite confusing. In this post I want to show you a quick tip to kickstart your Microsoft Graph API experience.
Requirements # Cloud admin account with Intune Administrator role assigned Ability to install Modules from the PowerShell gallery JWT # Just because you can’t see it… doesn’t mean it isn’t there: Due to the naturality of OAuth 2.0 and OpenID connect (these are the protocols involved for authorization and authentication in a cloud environment) we can capture short lived access tokens, also called Json Web Tokens (JWTs) directly from a browser. Tokens are usually valid between 50 and 60 minutes - just what we need to get some hands on with Microsoft Graph API and MEM automation.
The cool thing is actually that we don’t need any kind of app registration or additional permissions which can be quite some blocker in certain restricted environments (or staff unfamiliar with those technologies 😉).
App protection (also called MAM) policies have been around for a couple of years within MEM and I already used them in various projects to protect company data on unmanaged iOS and Android devices. One of the drawbacks with this approach is that we do not have full visibility about the usage and I tried to shed some light about this with a PowerShel reporting script that pulls data from the Microsoft Graph API.
Information visible within the portal # In the MEM portal we can find report data about the number of users that have checked-in to any MAM policy grouped by the respective app.
If we want to perform a wipe we will also be able to see the devices a user has registered:
Of course I was curious which additional data is available on the Microsoft Graph API and found the following resource storing app protection policy check in details: /users/{ID}/managedAppRegistrations.
Script # The script uses the Intune PowerShell SDK (could easily be ported to MSAL.PS because I wrote it already a couple of months ago) to enumerate all internal users within the tenant and will check the above mentioned managedAppRegistrations resource. At the end you are presented a flattened CSV report containig the following details:
Device and user-based certificates are commonly used for secure authentication for services like: MECM in HTTPS mode, Always On VPN, 802.1x for (wireless) LAN and so on. Mostly these certificates are deployed from an internal PKI and the certificate templates are somewhat outdated because everybody is afraid of touching these settings. As with any type of credentials - credential theft is also applicable for certificates and the corresponding private keys. So let’s dive in and learn the risk and how to reduce the attack surface.
Understanding cryptography providers # Before we start with the actual theft we need to know how certificates and the corresponding private keys are stored on Windows devices. Microsoft operating systems implement various cryptographic providers which can be either software or hardware based. The two most important ones are:
Microsoft Software Key Storage Provider “Standard” provider which stores keys software based and supports CNG (Crypto-Next Generation) Microsoft Platform Crypto Provider Hardware based which stores keys on a TPM (trusted platform module) and supports CNG as well When a client is requesting a new certificate from a CA he generates a key pair consisting of a private and public key with such a crpytographic provider.
Based on one of my older posts about PowerShell script signing with Azure DevOps I recently implemented a PowerShell script signing workflow with GitHub actions I wanted to share with the community.
Prerequisites # For this post the following prerequisites are required:
Code signing certificate in PFX format GitHub account Add variables to GitHub actions # Because GitHub variables can only be of string content we need to get the contents of the pfx file as base64 encoded string:
$pfxCertFilePath = "~\Downloads\CodeSigningCertificate.pfx" $pfxContent = Get-Content $pfxCertFilePath -Encoding Byte [System.Convert]::ToBase64String($pfxContent) | Set-Clipboard GitHub action variables # Add two variables as actions secrets:
BASE64_PFX: Base 64 encoded string of the PFX (automatically copied into your clipboard with the above commands) PFX_PASSWORD: Password for the private key of the pfx file
GitHub action workflow # Place the following workflow file within your git repository: .github/workflows/SignPowerShell.yaml whereas the name of the YAML file can be freely chosen.
The Send-MailMessage cmdlet has been around for a couple of years and is mostly used to send email messages from PowerShell. But with the deprecation and security flaws of legacy authentication it’s time for a better option which actually supports modern authentication. For this purpose we can use the Microsoft Graph API and the Microsoft Graph PowerShell SDK. The best thing is that this solution works without any service account and does not need any exclusions from conditional access.
Microsoft Graph resource # To send a mail we simply specify the user account from which we want to send the email:
POST: https://graph.microsoft.com/v1.0/users/sean.connery@dev.nicolonsky.ch/sendMail Create an app registration # Simply create a new app registration with the Mail.Send permissions and use a certificate for the authentication.
We need to take additional steps to limit the permissions of the app registration. Otherwise the app can send mails on behalf of any user in your tenant. To limit the permissions we leverage exchange application access policies.
Connect to Exchange Online with the ExchangeOnlineManagement PowerShell module Connect-ExchangeOnline
While fine-tuning and adjusting applocker policies for co-managed Windows 10 clients I got really annoyed by special characters commonly used in the German/Swiss language. The Intune portal seemed to use different encoding and didn’t allow me to just copy/paste the currently deployed policy and extend it with a new rule. I needed to request the original file that was uploaded to the tenant in order to adjust the rule. Instead of just accepting this I decided that it is time for an easier approach which I will share with you.
The actual issue # After uploading the XML with the applocker policies (in my case EXE rules), special characters like ‘ö’ or ‘ü’ have a weird encoding displayed in the portal. The next person that wants to edit the policy needs to take care to fix the unrecognized characters otherwise the publisher rule won’t work anymore.
Top: Portal view of the special characters, bottom: original file.
Fixing things # Save file with UTF-8 encoding # First, make sure that you saved an uploaded the file with UTF-8 encoding as this introduces support for most character sets. You can do this by selecting the encoding box in the right bottom of Visual Studio Code: