### Configure and Start AzureHound Service Source: https://github.com/specterops/azurehound/blob/main/README.md Configure AzureHound by following interactive prompts and then start the data collection service for BloodHound Enterprise. ```sh azurehound configure (follow prompts) azurehound start ``` -------------------------------- ### AzureHound Configure: Interactive Setup Source: https://context7.com/specterops/azurehound/llms.txt Runs an interactive wizard to create a persistent JSON configuration file for AzureHound service mode. It prompts for Azure region, tenant, authentication, and BloodHound Enterprise connection details. ```sh azurehound configure ``` -------------------------------- ### AzureHound Start: Using Config File Source: https://context7.com/specterops/azurehound/llms.txt Starts AzureHound as a persistent service using a previously created configuration file. The service polls BloodHound Enterprise for jobs and streams data. ```sh azurehound start -c ~/.config/azurehound/config.json ``` -------------------------------- ### AzureHound Start: Explicit Flag Configuration Source: https://context7.com/specterops/azurehound/llms.txt Starts AzureHound as a persistent service by explicitly passing all configuration parameters as command-line flags. This method avoids the need for a separate config file. ```sh azurehound start \ --tenant "$TENANT" \ --app-id "$APP_ID" \ --secret "$CLIENT_SECRET" \ --bhe-url "https://mybhe.bloodhoundenterprise.io" \ --bhe-token-id "$BHE_TOKEN_ID" \ --bhe-token "$BHE_TOKEN" ``` -------------------------------- ### Build AzureHound from Source Source: https://context7.com/specterops/azurehound/llms.txt Instructions for building the AzureHound binary from source using Go. Supports embedding version tags and building Docker images. ```sh # Prerequisites: Go 1.25+ git clone https://github.com/SpecterOps/AzureHound.git cd AzureHound # Build with version tag embedded go build -ldflags="-s -w -X github.com/bloodhoundad/azurehound/v2/constants.Version=$(git describe --tags --exact-match 2>/dev/null || git rev-parse HEAD)" # Build Docker image docker build --build-arg VERSION=v2.1.0 -t azurehound:v2.1.0 . ``` -------------------------------- ### AzureHound CLI Help Source: https://github.com/specterops/azurehound/blob/main/README.md Display the help information for the AzureHound command-line interface, including available commands and global flags. ```sh azurehound --help ``` -------------------------------- ### List Azure Tenant Data to Stdout Source: https://github.com/specterops/azurehound/blob/main/README.md Collect and print all Azure Tenant data to standard output. Requires username, password, and tenant ID for authentication. ```sh azurehound list -u "$USERNAME" -p "$PASSWORD" -t "$TENANT" ``` -------------------------------- ### client.NewClient Source: https://context7.com/specterops/azurehound/llms.txt Constructs an AzureClient from a config.Config struct. It initializes underlying REST clients, selects an authentication strategy, and resolves the tenant. The returned AzureClient is the primary entry point for data enumeration. ```APIDOC ## client.NewClient — Create an Azure API Client `NewClient` constructs an `AzureClient` from a `config.Config` struct. It creates two underlying REST clients (one for Microsoft Graph, one for Azure Resource Manager), selects the appropriate authentication strategy, and resolves the current tenant by calling the organization or tenants API. The returned `AzureClient` interface is the entry point for all data enumeration. ```go package main import ( "context" "fmt" "log" "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/client/config" "github.com/bloodhoundad/azurehound/v2/client/query" ) func main() { cfg := config.Config{ Tenant: "00000000-0000-0000-0000-000000000001", ApplicationId: "00000000-0000-0000-0000-000000000002", ClientSecret: "my-client-secret", } azClient, err := client.NewClient(cfg) if err != nil { log.Fatalf("failed to create azure client: %v", err) } defer azClient.CloseIdleConnections() tenant := azClient.TenantInfo() fmt.Printf("Connected to tenant: %s (%s)\n", tenant.DisplayName, tenant.TenantId) // Output: Connected to tenant: Contoso (00000000-0000-0000-0000-000000000001) // Authenticate via Managed Identity (system-assigned) miCfg := config.Config{ ManagedIdentity: true, } miClient, err := client.NewClient(miCfg) { log.Fatalf("managed identity auth failed: %v", err) } defer miClient.CloseIdleConnections() // Authenticate via pre-acquired JWT jwtCfg := config.Config{ JWT: "eyJ0eXAiOiJKV1Qi...", } jwtClient, err := client.NewClient(jwtCfg) { log.Fatalf("jwt auth failed: %v", err) } _ = jwtClient } ``` ``` -------------------------------- ### Build AzureHound from Source Source: https://github.com/specterops/azurehound/blob/main/README.md Compile the AzureHound project from source. Requires Go 1.25 or later. The build flags include version information derived from git tags or the current commit hash. ```sh go build -ldflags="-s -w -X github.com/bloodhoundad/azurehound/v2/constants.Version=`git describe tags --exact-match 2> /dev/null || git rev-parse HEAD`" ``` -------------------------------- ### Build and Run AzureHound in Docker Source: https://context7.com/specterops/azurehound/llms.txt Builds the AzureHound Docker image and runs it with specified environment variables for authentication and configuration. ```bash docker build --build-arg VERSION=v2.0.0 -t azurehound . docker run --rm \ -e AZUREHOUND_TENANT="$TENANT" \ -e AZUREHOUND_APP_ID="$APP_ID" \ -e AZUREHOUND_SECRET="$CLIENT_SECRET" \ -e AZUREHOUND_BHE_URL="https://mybhe.bloodhoundenterprise.io" \ -e AZUREHOUND_BHE_TOKEN_ID="$BHE_TOKEN_ID" \ -e AZUREHOUND_BHE_TOKEN="$BHE_TOKEN" \ azurehound start ``` -------------------------------- ### List Azure Tenant Data to File Source: https://github.com/specterops/azurehound/blob/main/README.md Collect and save all Azure Tenant data to a JSON file. Requires username, password, and tenant ID for authentication. Specify the output file using the -o flag. ```sh azurehound list -u "$USERNAME" -p "$PASSWORD" -t "$TENANT" -o "mytenant.json" ``` -------------------------------- ### Create Azure API Client with NewClient Source: https://context7.com/specterops/azurehound/llms.txt Constructs an AzureClient using config.Config. Supports authentication via client secret, managed identity, or pre-acquired JWT. Ensure correct configuration for your authentication method. ```go package main import ( "context" "fmt" "log" "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/client/config" "github.com/bloodhoundad/azurehound/v2/client/query" ) func main() { cfg := config.Config{ Tenant: "00000000-0000-0000-0000-000000000001", ApplicationId: "00000000-0000-0000-0000-000000000002", ClientSecret: "my-client-secret", } azClient, err := client.NewClient(cfg) if err != nil { log.Fatalf("failed to create azure client: %v", err) } defer azClient.CloseIdleConnections() tenant := azClient.TenantInfo() fmt.Printf("Connected to tenant: %s (%s)\n", tenant.DisplayName, tenant.TenantId) // Output: Connected to tenant: Contoso (00000000-0000-0000-0000-000000000001) // Authenticate via Managed Identity (system-assigned) miCfg := config.Config{ ManagedIdentity: true, } miClient, err := client.NewClient(miCfg) if err != nil { log.Fatalf("managed identity auth failed: %v", err) } defer miClient.CloseIdleConnections() // Authenticate via pre-acquired JWT jwtCfg := config.Config{ JWT: "eyJ0eXAiOiJKV1Qi...", } jwtClient, err := client.NewClient(jwtCfg) if err != nil { log.Fatalf("jwt auth failed: %v", err) } _ = jwtClient } ``` -------------------------------- ### ListAzureVirtualMachines Source: https://context7.com/specterops/azurehound/llms.txt Streams all virtual machines in a given subscription via the ARM Compute API. Uses API version `2021-07-01` by default. ```APIDOC ## AzureClient.ListAzureVirtualMachines — List Virtual Machines Streams all virtual machines in a given subscription via the ARM Compute API. Uses API version `2021-07-01` by default. ### Method ```go func (azClient *AzureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan Result[VirtualMachine] ``` ### Parameters #### Path Parameters - **subscriptionId** (string) - The ID of the subscription to list virtual machines from. #### Query Parameters - **params** (query.RMParams) - Parameters for querying the Azure Resource Manager API. ### Response #### Success Response - **VirtualMachine** (VirtualMachine) - An object representing a virtual machine. #### Error Response - **Error** (error) - An error encountered during the streaming process. ``` -------------------------------- ### List Azure Virtual Machines Source: https://context7.com/specterops/azurehound/llms.txt Streams all virtual machines in a given subscription via the ARM Compute API. Uses API version `2021-07-01` by default. ```go ctx := context.Background() subscriptionId := "aaaaaaaa-0000-0000-0000-000000000001" for result := range azClient.ListAzureVirtualMachines(ctx, subscriptionId, query.RMParams{}) { if result.Error != nil { log.Printf("error: %v", result.Error) break } vm := result.Ok fmt.Printf("VM: %s (id=%s)\n", vm.Name, vm.Id) } ``` -------------------------------- ### ListAzureADServicePrincipals Source: https://context7.com/specterops/azurehound/llms.txt Streams all service principals (application registrations' runtime identities) from Microsoft Graph. Pagination is handled automatically with a default page size of 999. ```APIDOC ## AzureClient.ListAzureADServicePrincipals — List Service Principals Streams all service principals (application registrations' runtime identities) from Microsoft Graph. Pagination is handled automatically with a default page size of 999. ### Method ```go func (azClient *AzureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan Result[ServicePrincipal] ``` ### Parameters #### Query Parameters - **params** (query.GraphParams) - Parameters for querying Microsoft Graph, including pagination. ### Response #### Success Response - **ServicePrincipal** (ServicePrincipal) - An object representing a service principal. #### Error Response - **Error** (error) - An error encountered during the streaming process. ``` -------------------------------- ### ListAzureKeyVaults Source: https://context7.com/specterops/azurehound/llms.txt Streams all Key Vaults in a given subscription. Uses the Key Vault API version `2019-09-01` by default. The CLI pipeline also enumerates access policies, owners, contributors, user access admins, and KV contributors. ```APIDOC ## AzureClient.ListAzureKeyVaults — List Key Vaults Streams all Key Vaults in a given subscription. Uses the Key Vault API version `2019-09-01` by default. The CLI pipeline also enumerates access policies, owners, contributors, user access admins, and KV contributors. ### Method ```go func (azClient *AzureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan Result[KeyVault] ``` ### Parameters #### Path Parameters - **subscriptionId** (string) - The ID of the subscription to list Key Vaults from. #### Query Parameters - **params** (query.RMParams) - Parameters for querying the Azure Resource Manager API. ### Response #### Success Response - **KeyVault** (KeyVault) - An object representing a Key Vault. #### Error Response - **Error** (error) - An error encountered during the streaming process. ``` -------------------------------- ### List Azure AD Service Principals Source: https://context7.com/specterops/azurehound/llms.txt Streams all service principals from Microsoft Graph. Pagination is handled automatically with a default page size of 999. ```go ctx := context.Background() for result := range azClient.ListAzureADServicePrincipals(ctx, query.GraphParams{}) { if result.Error != nil { log.Printf("error: %v", result.Error) break } sp := result.Ok fmt.Printf("ServicePrincipal: %s (appId=%s)\n", sp.DisplayName, sp.AppId) } ``` ```go // List owners of a specific service principal spId := "00000000-0000-0000-0000-000000000020" for result := range azClient.ListAzureADServicePrincipalOwners(ctx, spId, query.GraphParams{}) { if result.Error != nil { break } fmt.Printf("SP Owner raw: %s\n", string(result.Ok)) } ``` -------------------------------- ### AzureHound Configure: Custom Config Location Source: https://context7.com/specterops/azurehound/llms.txt Runs the interactive configuration wizard and specifies a custom file path for the output configuration JSON. This allows for centralized or specific configuration management. ```sh azurehound configure -c /etc/azurehound/config.json ``` -------------------------------- ### List Azure Key Vaults Source: https://context7.com/specterops/azurehound/llms.txt Streams all Key Vaults in a given subscription. Uses the Key Vault API version `2019-09-01` by default. The CLI pipeline also enumerates access policies, owners, contributors, user access admins, and KV contributors. ```go ctx := context.Background() subscriptionId := "aaaaaaaa-0000-0000-0000-000000000001" for result := range azClient.ListAzureKeyVaults(ctx, subscriptionId, query.RMParams{}) { if result.Error != nil { log.Printf("error: %v", result.Error) break } kv := result.Ok fmt.Printf("KeyVault: %s (id=%s)\n", kv.Name, kv.Id) } ``` -------------------------------- ### Enumerate Azure AD RBAC Roles and Assignments Source: https://context7.com/specterops/azurehound/llms.txt Streams Azure AD directory roles and their unified role assignments via Microsoft Graph. ```go ctx := context.Background() // List all directory roles for result := range azClient.ListAzureADRoles(ctx, query.GraphParams{}) { if result.Error != nil { break } role := result.Ok fmt.Printf("Role: %s (id=%s)\n", role.DisplayName, role.Id) } // List all unified role assignments for result := range azClient.ListAzureADRoleAssignments(ctx, query.GraphParams{}) { if result.Error != nil { break } ra := result.Ok fmt.Printf("RoleAssignment: principalId=%s roleDefinitionId=%s\n", ra.PrincipalId, ra.RoleDefinitionId) } ``` -------------------------------- ### List Azure Subscriptions Source: https://context7.com/specterops/azurehound/llms.txt Streams all Azure subscriptions accessible to the authenticated principal via the Azure Resource Manager API. ```go ctx := context.Background() for result := range azClient.ListAzureSubscriptions(ctx) { if result.Error != nil { log.Printf("error: %v", result.Error) break } sub := result.Ok fmt.Printf("Subscription: %s (id=%s, tenantId=%s)\n", sub.DisplayName, sub.SubscriptionId, sub.TenantId) } ``` -------------------------------- ### AzureHound List: Username/Password Authentication Source: https://context7.com/specterops/azurehound/llms.txt Collects all Azure AD and ARM objects using username and password authentication, writing the output to a JSON file. Ensure the password is kept secure. ```sh azurehound list \ -u "user@contoso.onmicrosoft.com" \ -p "$PASSWORD" \ -t "contoso.onmicrosoft.com" \ -o "contoso-data.json" ``` -------------------------------- ### List Azure AD Users with ListAzureADUsers Source: https://context7.com/specterops/azurehound/llms.txt Streams all Azure AD users using the Microsoft Graph API. Handles pagination automatically. Use specific select parameters to optimize data retrieval. ```go ctx := context.Background() params := query.GraphParams{ Select: []string{ "id", "displayName", "userPrincipalName", "accountEnabled", "userType", "mail", "onPremisesSyncEnabled", "onPremisesSecurityIdentifier", }, } count := 0 for result := range azClient.ListAzureADUsers(ctx, params) { if result.Error != nil { log.Printf("error fetching users: %v", result.Error) break } u := result.Ok fmt.Printf("User: %s (%s) enabled=%v type=%s\n", u.DisplayName, u.UserPrincipalName, u.AccountEnabled, u.UserType) count++ } fmt.Printf("Total users collected: %d\n", count) // Output: // User: Alice Smith (alice@contoso.com) enabled=true type=Member // User: Bob Jones (bob@contoso.com) enabled=true type=Guest // ... // Total users collected: 1342 ``` -------------------------------- ### ListAzureADRoles and ListAzureADRoleAssignments Source: https://context7.com/specterops/azurehound/llms.txt Streams Azure AD directory roles and their unified role assignments via Microsoft Graph. ```APIDOC ## AzureClient.ListAzureADRoles and AzureClient.ListAzureADRoleAssignments — Enumerate RBAC Streams Azure AD directory roles and their unified role assignments via Microsoft Graph. ### Method ```go func (azClient *AzureClient) ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan Result[Role] func (azClient *AzureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan Result[RoleAssignment] ``` ### Parameters #### Query Parameters - **params** (query.GraphParams) - Parameters for querying Microsoft Graph. ### Response #### Success Response (ListAzureADRoles) - **Role** (Role) - An object representing an Azure AD directory role. #### Success Response (ListAzureADRoleAssignments) - **RoleAssignment** (RoleAssignment) - An object representing a unified role assignment. #### Error Response - **Error** (error) - An error encountered during the streaming process. ``` -------------------------------- ### Create BloodHound Enterprise Ingest Client Source: https://context7.com/specterops/azurehound/llms.txt Creates an authenticated HTTP client for BloodHound Enterprise. Handles connection cycling, exponential backoff, and AWS GOAWAY errors. Requires BHE token ID and secret. ```go import ( "context" "net/url" "github.com/bloodhoundad/azurehound/v2/client/bloodhound" "github.com/go-logr/logr" ) bheURL, _ := url.Parse("https://mybhe.bloodhoundenterprise.io") logger := logr.Discard() bheClient, err := bloodhound.NewBHEClient( *bheURL, "token-id-uuid", // BHE token ID "token-secret", // BHE token secret "", // proxy URL (empty = no proxy) 1000, // max requests per connection before cycling 3, // max retries per request logger, ) if err != nil { log.Fatalf("failed to create BHE client: %v", err) } ctx := context.Background() // Update this client's info with BHE (required before job polling) updatedClient, err := bheClient.UpdateClient(ctx) if err != nil { log.Fatalf("failed to update client: %v", err) } // End any orphaned job from a previous crashed run if err := bheClient.EndOrphanedJob(ctx, updatedClient); err != nil { log.Fatalf("failed to end orphaned job: %v", err) } // Poll for available jobs jobs, err := bheClient.GetAvailableJobs(ctx) if err != nil { log.Fatalf("failed to get jobs: %v", err) } fmt.Printf("Available jobs: %d\n", len(jobs)) // Start and end a job if len(jobs) > 0 { jobID := jobs[0].ID bheClient.StartJob(ctx, jobID) // ... collect data ... bheClient.EndJob(ctx, models.JobStatusComplete, "Collection completed successfully") } ``` -------------------------------- ### List Azure Tenant Data using Azure CLI JWT Source: https://github.com/specterops/azurehound/blob/main/README.md Collect Azure Tenant data by reusing existing authentication from the Azure CLI. An access token is acquired using `az account get-access-token` and passed to AzureHound via the --jwt flag. ```sh JWT=$(az account get-access-token --resource https://graph.microsoft.com | jq -r .accessToken) azurehound list --jwt "$JWT" ``` -------------------------------- ### bloodhound.NewBHEClient Source: https://context7.com/specterops/azurehound/llms.txt Creates an authenticated HTTP client for communicating with a BloodHound Enterprise instance. It handles HMAC request signing, connection cycling, exponential backoff, and AWS GOAWAY errors automatically. ```APIDOC ## `bloodhound.NewBHEClient` — BloodHound Enterprise Ingest Client Creates an authenticated HTTP client for communicating with a BloodHound Enterprise instance. Uses HMAC request signing (`bhesignature`). Handles connection cycling, exponential backoff, and AWS GOAWAY errors automatically. ```go import ( "context" "net/url" "github.com/bloodhoundad/azurehound/v2/client/bloodhound" "github.com/go-logr/logr" ) bheURL, _ := url.Parse("https://mybhe.bloodhoundenterprise.io") logger := logr.Discard() bheClient, err := bloodhound.NewBHEClient( *bheURL, "token-id-uuid", // BHE token ID "token-secret", // BHE token secret "", // proxy URL (empty = no proxy) 1000, // max requests per connection before cycling 3, // max retries per request logger, ) if err != nil { log.Fatalf("failed to create BHE client: %v", err) } ctx := context.Background() // Update this client's info with BHE (required before job polling) updatedClient, err := bheClient.UpdateClient(ctx) if err != nil { log.Fatalf("failed to update client: %v", err) } // End any orphaned job from a previous crashed run if err := bheClient.EndOrphanedJob(ctx, updatedClient); err != nil { log.Fatalf("failed to end orphaned job: %v", err) } // Poll for available jobs jobs, err := bheClient.GetAvailableJobs(ctx) if err != nil { log.Fatalf("failed to get jobs: %v", err) } fmt.Printf("Available jobs: %d\n", len(jobs)) // Start and end a job if len(jobs) > 0 { jobID := jobs[0].ID bheClient.StartJob(ctx, jobID) // ... collect data ... bheClient.EndJob(ctx, models.JobStatusComplete, "Collection completed successfully") } ``` ``` -------------------------------- ### ListAzureADServicePrincipalOwners Source: https://context7.com/specterops/azurehound/llms.txt Lists the owners of a specific service principal. ```APIDOC ## AzureClient.ListAzureADServicePrincipalOwners — List Service Principal Owners Lists the owners of a specific service principal. ### Method ```go func (azClient *AzureClient) ListAzureADServicePrincipalOwners(ctx context.Context, spId string, params query.GraphParams) <-chan Result[string] ``` ### Parameters #### Path Parameters - **spId** (string) - The ID of the service principal. #### Query Parameters - **params** (query.GraphParams) - Parameters for querying Microsoft Graph. ### Response #### Success Response - **string** - Raw string representation of the owner information. #### Error Response - **Error** (error) - An error encountered during the retrieval of owners. ``` -------------------------------- ### Stream Collected Data to BloodHound Enterprise Source: https://context7.com/specterops/azurehound/llms.txt Ingests batches of Azure objects by reading from an input channel, serializing them as gzip-compressed JSON, and POSTing to the BHE ingest API. Returns true if any batch encountered an error. ```go ctx := context.Background() // Build the collection pipeline azClient, _ := client.NewClient(cfg) stream := listAll(ctx, azClient) // <-chan interface{} batches := pipeline.Batch(ctx.Done(), stream, 200, 10*time.Second) // <-chan []interface{} hasErrors := bheClient.Ingest(ctx, batches) if hasErrors { log.Println("ingest completed with errors; some data may be missing") } else { log.Println("ingest completed successfully") } ``` -------------------------------- ### AzureHound List: Filter by Subscription IDs Source: https://context7.com/specterops/azurehound/llms.txt Collects objects from specific Azure subscription IDs using service principal authentication. This allows for targeted data collection within a tenant. ```sh azurehound list \ --tenant "$TENANT" --app-id "$APP_ID" --secret "$SECRET" \ --subscription "sub-id-1" --subscription "sub-id-2" \ -o "filtered.json" ``` -------------------------------- ### AzureHound List: Azure AD Only Collection Source: https://context7.com/specterops/azurehound/llms.txt Collects only Azure Active Directory objects using username, password, and tenant ID. Use this when ARM enumeration is not required. ```sh azurehound list az-ad -u "$USERNAME" -p "$PASSWORD" -t "$TENANT" ``` -------------------------------- ### List Azure AD Groups with ListAzureADGroups Source: https://context7.com/specterops/azurehound/llms.txt Streams security-enabled Azure AD groups. The `listGroups` function filters and adds tenant metadata. Use `ListAzureADGroupMembers` and `ListAzureADGroupOwners` to retrieve group-specific information. ```go ctx := context.Background() // Filter to security-enabled groups only (as used in the CLI pipeline) params := query.GraphParams{Filter: "securityEnabled eq true"} for result := range azClient.ListAzureADGroups(ctx, params) { if result.Error != nil { log.Printf("error: %v", result.Error) break } g := result.Ok fmt.Printf("Group: %s (id=%s)\n", g.DisplayName, g.Id) } // List members of a specific group groupId := "00000000-0000-0000-0000-000000000010" for result := range azClient.ListAzureADGroupMembers(ctx, groupId, query.GraphParams{}) { if result.Error != nil { log.Printf("error: %v", result.Error) break } // result.Ok is json.RawMessage; unmarshal to inspect the member type fmt.Printf("Member raw: %s\n", string(result.Ok)) } // List owners of a specific group for result := range azClient.ListAzureADGroupOwners(ctx, groupId, query.GraphParams{}) { if result.Error != nil { break } fmt.Printf("Owner raw: %s\n", string(result.Ok)) } ``` -------------------------------- ### AzureClient.ListAzureADUsers Source: https://context7.com/specterops/azurehound/llms.txt Streams all Azure AD users via the Microsoft Graph API (`/beta/users`). Returns a channel of `AzureResult[azure.User]`, handling pagination automatically. ```APIDOC ## AzureClient.ListAzureADUsers — List Azure AD Users Streams all Azure AD users via the Microsoft Graph API (`/beta/users`). Returns a channel of `AzureResult[azure.User]`; each item is either a hydrated `azure.User` or an error. Automatically handles pagination via `@odata.nextLink`. ```go ctx := context.Background() params := query.GraphParams{ Select: []string{ "id", "displayName", "userPrincipalName", "accountEnabled", "userType", "mail", "onPremisesSyncEnabled", "onPremisesSecurityIdentifier", }, } count := 0 for result := range azClient.ListAzureADUsers(ctx, params) { if result.Error != nil { log.Printf("error fetching users: %v", result.Error) break } u := result.Ok fmt.Printf("User: %s (%s) enabled=%v type=%s\n", u.DisplayName, u.UserPrincipalName, u.AccountEnabled, u.UserType) count++ } fmt.Printf("Total users collected: %d\n", count) // Output: // User: Alice Smith (alice@contoso.com) enabled=true type=Member // User: Bob Jones (bob@contoso.com) enabled=true type=Guest // ... // Total users collected: 1342 ``` ``` -------------------------------- ### BHEClient.Ingest Source: https://context7.com/specterops/azurehound/llms.txt Streams collected data to BloodHound Enterprise by reading batches of Azure objects from an input channel, serializing them as gzip-compressed JSON, and POSTing them to the BHE `/api/v2/ingest` endpoint. Returns `true` if any batch encountered an error. ```APIDOC ## `BHEClient.Ingest` — Stream Collected Data to BloodHound Enterprise `Ingest` reads batches of Azure objects from an input channel, serializes them as gzip-compressed JSON, and POSTs them to the BHE `/api/v2/ingest` endpoint. Returns `true` if any batch encountered an error. ```go ctx := context.Background() // Build the collection pipeline azClient, _ := client.NewClient(cfg) stream := listAll(ctx, azClient) // <-chan interface{} batches := pipeline.Batch(ctx.Done(), stream, 200, 10*time.Second) // <-chan []interface{} hasErrors := bheClient.Ingest(ctx, batches) if hasErrors { log.Println("ingest completed with errors; some data may be missing") } else { log.Println("ingest completed successfully") } ``` ``` -------------------------------- ### ListAzureSubscriptions Source: https://context7.com/specterops/azurehound/llms.txt Streams all Azure subscriptions accessible to the authenticated principal via the Azure Resource Manager API. ```APIDOC ## AzureClient.ListAzureSubscriptions — List Subscriptions Streams all Azure subscriptions accessible to the authenticated principal via the Azure Resource Manager API. ### Method ```go func (azClient *AzureClient) ListAzureSubscriptions(ctx context.Context) <-chan Result[Subscription] ``` ### Response #### Success Response - **Subscription** (Subscription) - An object representing an Azure subscription. #### Error Response - **Error** (error) - An error encountered during the streaming process. ``` -------------------------------- ### AzureHound List: Service Principal Client Secret Authentication Source: https://context7.com/specterops/azurehound/llms.txt Collects all Azure AD and ARM objects using a service principal's client ID, secret, and tenant ID, saving the data to a JSON file. This is a common method for automated collection. ```sh azurehound list \ --tenant "00000000-0000-0000-0000-000000000001" \ --app-id "00000000-0000-0000-0000-000000000002" \ --secret "$CLIENT_SECRET" \ -o "contoso-data.json" ``` -------------------------------- ### AzureHound List: Azure RM Only Collection Source: https://context7.com/specterops/azurehound/llms.txt Collects only Azure Resource Manager objects using username, password, and tenant ID. Use this when AAD enumeration is not required. ```sh azurehound list az-rm -u "$USERNAME" -p "$PASSWORD" -t "$TENANT" ``` -------------------------------- ### AzureClient.ListAzureADGroups Source: https://context7.com/specterops/azurehound/llms.txt Streams all security-enabled Azure AD groups. The `listGroups` pipeline function filters and wraps results in a `models.Group` with tenant metadata. ```APIDOC ## AzureClient.ListAzureADGroups — List Security Groups Streams all security-enabled Azure AD groups. The `listGroups` pipeline function adds filters and wraps results in a `models.Group` with tenant metadata before emitting them. ```go ctx := context.Background() // Filter to security-enabled groups only (as used in the CLI pipeline) params := query.GraphParams{Filter: "securityEnabled eq true"} for result := range azClient.ListAzureADGroups(ctx, params) { if result.Error != nil { log.Printf("error: %v", result.Error) break } g := result.Ok fmt.Printf("Group: %s (id=%s)\n", g.DisplayName, g.Id) } // List members of a specific group groupId := "00000000-0000-0000-0000-000000000010" for result := range azClient.ListAzureADGroupMembers(ctx, groupId, query.GraphParams{}) { if result.Error != nil { log.Printf("error: %v", result.Error) break } // result.Ok is json.RawMessage; unmarshal to inspect the member type fmt.Printf("Member raw: %s\n", string(result.Ok)) } // List owners of a specific group for result := range azClient.ListAzureADGroupOwners(ctx, groupId, query.GraphParams{}) { if result.Error != nil { break } fmt.Printf("Owner raw: %s\n", string(result.Ok)) } ``` ``` -------------------------------- ### AzureHound List: Filter by Management Group Source: https://context7.com/specterops/azurehound/llms.txt Collects objects from all subscriptions under a specified management group using service principal authentication. This is useful for hierarchical data collection. ```sh azurehound list \ --tenant "$TENANT" --app-id "$APP_ID" --secret "$SECRET" \ --management-group "mg-root-id" \ -o "mgmt-group.json" ``` -------------------------------- ### AzureHound List: Azure CLI JWT Authentication Source: https://context7.com/specterops/azurehound/llms.txt Collects Azure objects using a pre-acquired Azure CLI JWT for authentication. This method is useful when Azure CLI is already configured and authenticated. ```sh JWT=$(az account get-access-token --resource https://graph.microsoft.com | jq -r .accessToken) azurehound list --jwt "$JWT" -o "contoso-data.json" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.