【问题标题】:Create KMS key policy in Go在 Go 中创建 KMS 密钥策略
【发布时间】:2022-10-07 08:10:43
【问题描述】:

我正在尝试使用 AWS SDK v2 函数调用创建 KMS 密钥:

conn := kms.NewFromConfig(cfg)

input := kms.CreateKeyInput{
    KeySpec:     types.KeySpecEccNistP521,
    KeyUsage:    types.KeyUsageTypeSignVerify,
    MultiRegion: aws.Bool(true),
    Policy:      aws.String(\"\")
}

output, err := conn.CreateKey(ctx, &input)

我遇到的问题是我不确定如何为密钥生成策略。我假设我可以为 IAM 策略文档创建 JSON,但我不觉得自己生成它的前景特别有吸引力。是否有可用于生成此文档的包或库?

  • 它只是 json。这就像编程,但你不必考虑任何逻辑
  • @erik258 是的,但我宁愿能够使用具体类型来构造它,而不是操纵 JSON 或映射

标签: go amazon-kms


【解决方案1】:

我最终创建了自己的策略类:

// Policy describes a policy document that can be used to configure permissions in IAM
type Policy struct {
    Version    string       `json:"Version"`
    ID         string       `json:"Id"`
    Statements []*Statement `json:"Statement"`
}

// Statement describes a set of permissions that define what resources and users should have access
// to the resources described therein
type Statement struct {
    ID            string     `json:"Sid"`
    Effect        Effect     `json:"Effect"`
    PrincipalArns Principals `json:"Principal"`
    ActionArns    Actions    `json:"Action"`
    ResourceArns  Resources  `json:"Resource"`
}

// Principals describes a list of principals associated with a policy statement
type Principals []string

// MarhsalJSON converts a Principals collection to JSON
func (p Principals) MarshalJSON() ([]byte, error) {

    // First, get the inner string from the list of principals
    var inner string
    if len(p) > 1 {
        inner = marshal(p...)
    } else if len(p) == 1 {
        inner = strings.Quote(p[0], "\"")
    } else {
        return nil, fmt.Errorf("Principal must contain at least one element")
    }

    // Next, create the principal block and return it
    return []byte(fmt.Sprintf("{\"AWS\": %s}", inner)), nil
}

// Actions describes a list of actions that may or may not be taken by principals with regard to the
// resources described in a policy statement
type Actions []Action

// MarshalJSON converts an Actions collection to JSON
func (a Actions) MarshalJSON() ([]byte, error) {

    // First, get the inner string from the list of actions
    var inner string
    if len(a) > 1 {
        inner = marshal(a...)
    } else if len(a) == 1 {
        inner = strings.Quote(a[0], "\"")
    } else {
        return nil, fmt.Errorf("Action must contain at least one element")
    }

    // Next, create the action block and return it
    return []byte(inner), nil
}

// Resources describes a list of resources effected by the policy statement
type Resources []string

// MarshalJSON converts a Resources collection to JSON
func (r Resources) MarshalJSON() ([]byte, error) {

    // First, get the inner string from the list of actions
    var inner string
    if len(r) > 1 {
        inner = marshal(r...)
    } else if len(r) == 1 {
        inner = strings.Quote(r[0], "\"")
    } else {
        return nil, fmt.Errorf("Resource must contain at least one element")
    }

    // Next, create the action block and return it
    return []byte(inner), nil
}

// Helper function that converts a list of items to a JSON-string
func marshal[S ~string](items ...S) string {
    return "[" + strings.ModifyAndJoin(func(item string) string { return strings.Quote(item, "\"") }, ",", items...) + "]"
}

// Effect describes the effect a policy statement will have upon the resource and for the actions described
type Effect string

var (

    // Allow to grant access of the resource and actions to the principals described in the policy statement
    Allow = Effect("Allow")

    // Deny to deny access of the resource and actions from the principals described in the policy statement
    Deny = Effect("Deny")
)

// Action describes a valid operation that may be made against a particular AWS resource
type Action string

// Describes the various action types available to AWS
var (
    CancelKeyDeletion                   = Action("kms:CancelKeyDeletion")
    ConnectCustomKeyStore               = Action("kms:ConnectCustomKeyStore")
    CreateAlias                         = Action("kms:CreateAlias")
    CreateCustomKeyStore                = Action("kms:CreateCustomKeyStore")
    CreateGrant                         = Action("kms:CreateGrant")
    CreateKey                           = Action("kms:CreateKey")
    Decrypt                             = Action("kms:Decrypt")
    DeleteAlias                         = Action("kms:DeleteAlias")
    DeleteCustomKeyStore                = Action("kms:DeleteCustomKeyStore")
    DeleteImportedKeyMaterial           = Action("kms:DeleteImportedKeyMaterial")
    DescribeCustomKeyStores             = Action("kms:DescribeCustomKeyStores")
    DescribeKey                         = Action("kms:DescribeKey")
    DisableKey                          = Action("kms:DisableKey")
    DisableKeyRotation                  = Action("kms:DisableKeyRotation")
    DisconnectCustomKeyStore            = Action("kms:DisconnectCustomKeyStore")
    EnableKey                           = Action("kms:EnableKey")
    EnableKeyRotation                   = Action("kms:EnableKeyRotation")
    Encrypt                             = Action("kms:Encrypt")
    GenerateDataKey                     = Action("kms:GenerateDataKey")
    GenerateDataKeyPair                 = Action("kms:GenerateDataKeyPair")
    GenerateDataKeyPairWithoutPlaintext = Action("kms:GenerateDataKeyPairWithoutPlaintext")
    GenerateDataKeyWithoutPlaintext     = Action("kms:GenerateDataKeyWithoutPlaintext")
    GenerateMac                         = Action("kms:GenerateMac")
    GenerateRandom                      = Action("kms:GenerateRandom")
    GetKeyPolicy                        = Action("kms:GetKeyPolicy")
    GetKeyRotationStatus                = Action("kms:GetKeyRotationStatus")
    GetParametersForImport              = Action("kms:GetParametersForImport")
    GetPublicKey                        = Action("kms:GetPublicKey")
    ImportKeyMaterial                   = Action("kms:ImportKeyMaterial")
    ListAliases                         = Action("kms:ListAliases")
    ListGrants                          = Action("kms:ListGrants")
    ListKeyPolicies                     = Action("kms:ListKeyPolicies")
    ListKeys                            = Action("kms:ListKeys")
    ListResourceTags                    = Action("kms:ListResourceTags")
    ListRetirableGrants                 = Action("kms:ListRetirableGrants")
    PutKeyPolicy                        = Action("kms:PutKeyPolicy")
    ReEncryptFrom                       = Action("kms:ReEncryptFrom")
    ReEncryptTo                         = Action("kms:ReEncryptTo")
    ReplicateKey                        = Action("kms:ReplicateKey")
    RetireGrant                         = Action("kms:RetireGrant")
    RevokeGrant                         = Action("kms:RevokeGrant")
    ScheduleKeyDeletion                 = Action("kms:ScheduleKeyDeletion")
    Sign                                = Action("kms:Sign")
    TagResource                         = Action("kms:TagResource")
    UntagResource                       = Action("kms:UntagResource")
    UpdateAlias                         = Action("kms:UpdateAlias")
    UpdateCustomKeyStore                = Action("kms:UpdateCustomKeyStore")
    UpdateKeyDescription                = Action("kms:UpdateKeyDescription")
    UpdatePrimaryRegion                 = Action("kms:UpdatePrimaryRegion")
    Verify                              = Action("kms:Verify")
    VerifyMac                           = Action("kms:VerifyMac")
    KmsAll                              = Action("kms:*")
)

然后我可以在我的代码中使用它,如下所示:

conn := kms.NewFromConfig(cfg)

policy := Policy {
    Version: "2012-10-17",
    ID:      "test-key",
    Statements: []*policy.Statement{
        {
            ID:            "test-failure",
            Effect:        policy.Allow,
            PrincipalArns: []string{"arn:aws:kms:eu-west-2:111122223333:root"},
            ActionArns:    policy.Actions{policy.KmsAll},
            ResourceArns:  []string{"*"},
        },
    },
}

pData, err := json.Marshal(policy)
if err != nil {
   return err
}

input := kms.CreateKeyInput{
    KeySpec:     types.KeySpecEccNistP521,
    KeyUsage:    types.KeyUsageTypeSignVerify,
    MultiRegion: aws.Bool(true),
    Policy:      aws.String(string(pData)),
}

output, err := conn.CreateKey(ctx, &input)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 2019-08-24
    • 1970-01-01
    • 2019-11-18
    相关资源
    最近更新 更多