Skip to content

Commit a5878c6

Browse files
authored
fix(KMS): handle deleted key better (#28)
1 parent 9c4413f commit a5878c6

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

ape_aws/accounts.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ def __init__(self, *args, **kwargs):
2525
@property
2626
def keys(self) -> dict[str, KmsKey]: # type: ignore[syntax]
2727
try:
28-
return super(AwsClient, self).keys
28+
keys = super(AwsClient, self).keys
2929

3030
except AwsAccessError as e:
3131
# NOTE: Do not raise here, instead just log warning (prevent issues w/ Ape API)
3232
logger.warning(str(e))
3333
return {}
3434

35+
return {alias: key for alias, key in keys.items() if key.enabled}
36+
3537
@property
3638
def aliases(self) -> Iterator[str]:
3739
yield from iter(self.keys)

ape_aws/iam/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class IamClient(Session):
9898
KEY_ACCESS_POLICY = dict(
9999
Sid="ApeAWSv1",
100100
Effect="Allow",
101-
Action=["kms:ListAliases", "kms:Sign", "kms:Verify", "kms:GetPublicKey"],
101+
Action=["kms:ListAliases", "kms:Sign", "kms:Verify", "kms:GetPublicKey", "kms:DescribeKey"],
102102
Resource="*",
103103
)
104104

@@ -115,7 +115,7 @@ def users(self) -> dict[str, IamUser]:
115115

116116
except BotoCoreError as e:
117117
# NOTE: Handle here since `.users` is the main access point for the external API
118-
raise AwsAccessError(e)
118+
raise AwsAccessError(e) from e
119119

120120
users = map(IamUser.model_validate, response.get("Users", []))
121121

ape_aws/kms/client.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from itertools import chain
44
from typing import TYPE_CHECKING, ClassVar
55

6-
from ape.types import AddressType
6+
from ape.types import AddressType, HexBytes
77
from botocore.exceptions import BotoCoreError # type: ignore[import-untyped]
88
from pydantic import BaseModel, Field, SecretStr, field_validator
99

@@ -76,6 +76,14 @@ class KmsKey(BaseModel):
7676
def prune_alias_prepend(cls, value: str):
7777
return value.replace("alias/ape-aws/v1/", "")
7878

79+
@property
80+
def metadata(self) -> dict:
81+
return self.kms_client.describe_key(KeyId=self.id)["KeyMetadata"]
82+
83+
@property
84+
def enabled(self) -> bool:
85+
return self.metadata.get("Enabled", False)
86+
7987
@property
8088
def alias(self) -> str:
8189
if self.cached_alias is not None:
@@ -96,8 +104,12 @@ def set_alias(self, alias: str):
96104
self.cached_alias = alias
97105

98106
@property
99-
def public_key(self):
100-
return self.kms_client.get_public_key(KeyId=self.id)["PublicKey"]
107+
def public_key(self) -> HexBytes:
108+
try:
109+
return HexBytes(self.kms_client.get_public_key(KeyId=self.id)["PublicKey"][-64:])
110+
except (self.kms_client.exceptions.KMSInvalidStateException, BotoCoreError) as e:
111+
# NOTE: Handle here since `.keys` is the main access point for the external API
112+
raise AwsAccessError(e) from e
101113

102114
@property
103115
def address(self) -> AddressType:
@@ -106,7 +118,7 @@ def address(self) -> AddressType:
106118

107119
from eth_utils import keccak, to_checksum_address
108120

109-
return AddressType(to_checksum_address(keccak(self.public_key[-64:])[-20:].hex().lower()))
121+
return AddressType(to_checksum_address(keccak(self.public_key)[-20:]))
110122

111123
def add_tags(self, tags: list[dict[str, str]]):
112124
self.kms_client.tag_resource(KeyId=self.id, Tags=tags)
@@ -189,7 +201,7 @@ def keys(self) -> dict[str, KmsKey]:
189201
key_data = filter(lambda k: k["AliasName"].startswith("alias/ape-aws/"), chain(*pages))
190202
except BotoCoreError as e:
191203
# NOTE: Handle here since `.keys` is the main access point for the external API
192-
raise AwsAccessError(e)
204+
raise AwsAccessError(e) from e
193205

194206
keys = map(KmsKey.model_validate, key_data)
195207
return {key.alias: key for key in keys}

0 commit comments

Comments
 (0)