Compare commits
9
Commits
9d2379bb3e
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
955b6640c3 | ||
|
|
ea791df4aa | ||
|
|
a587f0ab71 | ||
|
|
93f1b191c8 | ||
|
|
a51ed76119 | ||
|
|
5bca7e176a | ||
|
|
684d3f5a75 | ||
|
|
99fca0f746 | ||
|
|
9b1e2fb447 |
@@ -16,3 +16,4 @@
|
|||||||
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
|
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
|
||||||
- [WSP local build and test](wsp_local_build_and_test.md) — core-services-cloud on this box: dotnet via nix, artifactory creds from `~/.artifactoryenv` sourced per command, how to tell auth failure from a code failure
|
- [WSP local build and test](wsp_local_build_and_test.md) — core-services-cloud on this box: dotnet via nix, artifactory creds from `~/.artifactoryenv` sourced per command, how to tell auth failure from a code failure
|
||||||
- [WSP-32957 PIM migration](wsp_32957_pim_migration.md) — AKS RBAC to PIM + AutoPerm decommission; prod is in the Technical Preview subscription, three tenants; resume via `~/code/WSP-32957-CONTINUATION.md`
|
- [WSP-32957 PIM migration](wsp_32957_pim_migration.md) — AKS RBAC to PIM + AutoPerm decommission; prod is in the Technical Preview subscription, three tenants; resume via `~/code/WSP-32957-CONTINUATION.md`
|
||||||
|
- [Entra group member reads](entra_group_member_reads.md) — `az ad group member list` hides service principal members; use the servicePrincipal cast or transitiveMemberOf, and trust the Terraform plan over it
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: entra-group-member-reads
|
||||||
|
description: az ad group member list and Graph /members silently omit service principal members — use the servicePrincipal cast or transitiveMemberOf when a group is expected to hold an SPN.
|
||||||
|
metadata:
|
||||||
|
node_type: memory
|
||||||
|
type: reference
|
||||||
|
---
|
||||||
|
|
||||||
|
`az ad group member list --group <id>` and `GET /groups/{id}/members` both return an **empty collection**, with no error, for a group whose only members are service principals — at least when called with Lyra's user account. The read looks authoritative and is not.
|
||||||
|
|
||||||
|
**Reliable reads instead:**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# members, cast to the type that is being hidden
|
||||||
|
az rest --method get --url "https://graph.microsoft.com/v1.0/groups/<gid>/members/microsoft.graph.servicePrincipal?\$select=id,displayName"
|
||||||
|
|
||||||
|
# count, which does not filter
|
||||||
|
az rest --method get --url "https://graph.microsoft.com/v1.0/groups/<gid>/members/\$count" --headers ConsistencyLevel=eventual
|
||||||
|
|
||||||
|
# from the principal's side
|
||||||
|
az rest --method get --url "https://graph.microsoft.com/v1.0/servicePrincipals/<spid>/transitiveMemberOf?\$select=id,displayName"
|
||||||
|
az rest --method post --url "https://graph.microsoft.com/v1.0/servicePrincipals/<spid>/checkMemberGroups" \
|
||||||
|
--body '{"groupIds":["<gid>"]}' --headers "Content-Type=application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
**How to apply:** any group that deployment or automation identities belong to — `*-cluster-admins`, `*-keyvault`, anything created by `rg-prereqs` — must be checked with one of the above before concluding it is empty. Cross-check against Terraform: a plan reporting "No changes" against a `members` attribute is strong evidence the membership is present, and outranks the `az` read. On 2026-08-28 the plain read produced a Bug (WSP-33432, cancelled) claiming five `*-cluster-admins` groups across three tenants had been emptied; all five held their deployment principals the whole time.
|
||||||
|
|
||||||
|
Related: [[wsp-32957-pim-migration]].
|
||||||
@@ -313,6 +313,14 @@ in
|
|||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
set -g @catppuccin_flavor 'mocha'
|
set -g @catppuccin_flavor 'mocha'
|
||||||
set -g @catppuccin_window_status_style 'rounded'
|
set -g @catppuccin_window_status_style 'rounded'
|
||||||
|
# Catppuccin's default window text is #T, the pane title, which every
|
||||||
|
# program in the pane is free to overwrite -- the shell writes the
|
||||||
|
# hostname, Claude Code writes its current task, and a hand-set window
|
||||||
|
# name never appears. Show the window name instead, falling back to the
|
||||||
|
# pane title when the window holds a single pane and the two carry the
|
||||||
|
# same information anyway.
|
||||||
|
set -g @catppuccin_window_text ' #{?#{==:#{window_panes},1},#T,#W}'
|
||||||
|
set -g @catppuccin_window_current_text ' #{?#{==:#{window_panes},1},#T,#W}'
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
resurrect # save/restore sessions
|
resurrect # save/restore sessions
|
||||||
@@ -357,6 +365,17 @@ in
|
|||||||
set -g renumber-windows on
|
set -g renumber-windows on
|
||||||
set -g set-clipboard on
|
set -g set-clipboard on
|
||||||
|
|
||||||
|
# Pane titles on the border, but only once a window is split -- a single
|
||||||
|
# pane's title is already in the status bar. pane-border-status takes no
|
||||||
|
# format, so the hook recomputes it whenever the layout changes, which
|
||||||
|
# covers both splitting and closing a pane.
|
||||||
|
set -g pane-border-format " #P #{pane_title} "
|
||||||
|
set -g pane-border-status off
|
||||||
|
set-hook -g window-layout-changed 'set -Fw pane-border-status "#{?#{>:#{window_panes},1},top,off}"'
|
||||||
|
|
||||||
|
# Pane titles have no default binding.
|
||||||
|
bind T command-prompt -p "pane title:" "select-pane -T '%%'"
|
||||||
|
|
||||||
# Catppuccin v2 statusline. Must run after the plugin has loaded;
|
# Catppuccin v2 statusline. Must run after the plugin has loaded;
|
||||||
# home-manager appends this extraConfig after the whole plugin list.
|
# home-manager appends this extraConfig after the whole plugin list.
|
||||||
set -g status-left-length 100
|
set -g status-left-length 100
|
||||||
|
|||||||
@@ -161,6 +161,11 @@
|
|||||||
dock = {
|
dock = {
|
||||||
show-recents = false;
|
show-recents = false;
|
||||||
mru-spaces = false; # don't reorder spaces by use
|
mru-spaces = false; # don't reorder spaces by use
|
||||||
|
# Disable hot-corners
|
||||||
|
wvous-tr-corner = 1;
|
||||||
|
wvous-tl-corner = 1;
|
||||||
|
wvous-bl-corner = 1;
|
||||||
|
wvous-br-corner = 1;
|
||||||
};
|
};
|
||||||
finder = {
|
finder = {
|
||||||
AppleShowAllExtensions = true;
|
AppleShowAllExtensions = true;
|
||||||
|
|||||||
@@ -47,7 +47,23 @@
|
|||||||
pkgs.terraform-docs # generate Terraform module docs
|
pkgs.terraform-docs # generate Terraform module docs
|
||||||
pkgs.yq-go # jq for YAML
|
pkgs.yq-go # jq for YAML
|
||||||
pkgs.gcx # Grafana Cloud CLI (dashboards, SLOs, synthetics, alerts)
|
pkgs.gcx # Grafana Cloud CLI (dashboards, SLOs, synthetics, alerts)
|
||||||
|
|
||||||
|
# WSL ships no xdg-open, so anything that shells out to a browser dies with
|
||||||
|
# `exec: "xdg-open,x-www-browser,www-browser": executable file not found`.
|
||||||
|
# kubelogin's interactive login is the one that bites: it is the login mode
|
||||||
|
# the shared cluster kubeconfig uses. Hand the URL to Windows instead.
|
||||||
|
# (wslu, the usual answer, is gone from nixpkgs -- upstream archived it.)
|
||||||
|
(pkgs.writeShellScriptBin "xdg-open" ''
|
||||||
|
url="$1"
|
||||||
|
if command -v powershell.exe >/dev/null 2>&1; then
|
||||||
|
exec powershell.exe -NoProfile -Command "Start-Process '$url'"
|
||||||
|
fi
|
||||||
|
exec explorer.exe "$url"
|
||||||
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Honoured by tools that read $BROWSER rather than calling xdg-open.
|
||||||
|
home.sessionVariables.BROWSER = "xdg-open";
|
||||||
services.ssh-agent.enable = true;
|
services.ssh-agent.enable = true;
|
||||||
|
|
||||||
# Colourised kubectl. enableAlias points `kubectl` at kubecolor, which parses
|
# Colourised kubectl. enableAlias points `kubectl` at kubecolor, which parses
|
||||||
|
|||||||
Reference in New Issue
Block a user