88 "encoding/hex"
99 "errors"
1010 "fmt"
11+ "net/http"
1112 "regexp"
1213
1314 "go.mondoo.com/cnquery/v12/llx"
@@ -16,6 +17,7 @@ import (
1617 "go.mondoo.com/cnquery/v12/providers/azure/connection"
1718 "go.mondoo.com/cnquery/v12/types"
1819
20+ "github.com/Azure/azure-sdk-for-go/sdk/azcore"
1921 "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
2022 keyvault "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault"
2123 "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates"
@@ -438,6 +440,91 @@ func (a *mqlAzureSubscriptionKeyVaultServiceKey) versions() ([]any, error) {
438440 return res , nil
439441}
440442
443+ func (a * mqlAzureSubscriptionKeyVaultServiceKey ) rotationPolicy () (* mqlAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject , error ) {
444+ conn := a .MqlRuntime .Connection .(* connection.AzureConnection )
445+ id := a .Kid .Data
446+ kvid , err := parseKeyVaultId (id )
447+ if err != nil {
448+ return nil , err
449+ }
450+
451+ if kvid .Type != "keys" {
452+ return nil , errors .New ("only key ids are supported" )
453+ }
454+
455+ client , err := azkeys .NewClient (kvid .BaseUrl , conn .Token (), & azkeys.ClientOptions {
456+ ClientOptions : conn .ClientOptions (),
457+ })
458+ if err != nil {
459+ return nil , err
460+ }
461+
462+ ctx := context .Background ()
463+ policyResp , err := client .GetKeyRotationPolicy (ctx , kvid .Name , nil )
464+ if err != nil {
465+ // Only treat 404 (not found) as "policy doesn't exist"
466+ // Return actual errors for permissions, network issues, etc.
467+ var respErr * azcore.ResponseError
468+ if errors .As (err , & respErr ) && respErr .StatusCode == http .StatusNotFound {
469+ // Rotation policy doesn't exist, return a resource with enabled=false
470+ resource , err := CreateResource (a .MqlRuntime ,
471+ ResourceAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject ,
472+ map [string ]* llx.RawData {
473+ "__id" : llx .StringData (id + "/rotationPolicy" ),
474+ "lifetimeActions" : llx .ArrayData ([]any {}, types .Dict ),
475+ "attributes" : llx .DictData (map [string ]any {}),
476+ "enabled" : llx .BoolData (false ),
477+ },
478+ )
479+ if err != nil {
480+ return nil , err
481+ }
482+ return resource .(* mqlAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject ), nil
483+ }
484+ // Return the actual error for non-404 cases
485+ return nil , err
486+ }
487+
488+ lifetimeActions := []any {}
489+ rotationEnabled := false
490+ if policyResp .LifetimeActions != nil {
491+ for _ , action := range policyResp .LifetimeActions {
492+ actionDict , err := convert .JsonToDict (action )
493+ if err != nil {
494+ return nil , err
495+ }
496+ lifetimeActions = append (lifetimeActions , actionDict )
497+
498+ if action .Action != nil && string (* action .Action .Type ) == "Rotate" {
499+ rotationEnabled = true
500+ }
501+ }
502+ }
503+
504+ attributes := map [string ]any {}
505+ if policyResp .Attributes != nil {
506+ attributesDict , err := convert .JsonToDict (policyResp .Attributes )
507+ if err != nil {
508+ return nil , err
509+ }
510+ attributes = attributesDict
511+ }
512+
513+ resource , err := CreateResource (a .MqlRuntime ,
514+ ResourceAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject ,
515+ map [string ]* llx.RawData {
516+ "__id" : llx .StringData (id + "/rotationPolicy" ),
517+ "lifetimeActions" : llx .ArrayData (lifetimeActions , types .Dict ),
518+ "attributes" : llx .DictData (attributes ),
519+ "enabled" : llx .BoolData (rotationEnabled ),
520+ },
521+ )
522+ if err != nil {
523+ return nil , err
524+ }
525+ return resource .(* mqlAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject ), nil
526+ }
527+
441528func (a * mqlAzureSubscriptionKeyVaultServiceCertificate ) certName () (string , error ) {
442529 id := a .Id .Data
443530 kvid , err := parseKeyVaultId (id )
@@ -628,3 +715,7 @@ func initAzureSubscriptionKeyVaultServiceVault(runtime *plugin.Runtime, args map
628715
629716 return nil , nil , errors .New ("azure key vault does not exist" )
630717}
718+
719+ func (a * mqlAzureSubscriptionKeyVaultServiceKeyRotationPolicyObject ) id () (string , error ) {
720+ return a .__id , nil
721+ }
0 commit comments