`aws login` sometimes writes a login cache that can't be read back (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT)
维护者通常 2 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 44/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- aws, python
- 领域
- authentication, cli
调研方向
Start with awscli/botocore/credentials.py at _load_private_key and the key generation and export calls in awscli/customizations/login/utils.py. Reproduce the failure using the supplied loop on Linux with the pinned awscrt version, then inspect the linked aws-c-cal issue for the underlying fix. Done means cached keys load successfully and malformed cached keys produce the expected LoginTokenLoadError instead of a traceback.
由索引模型根据 Issue 内容生成。
描述
Describe the bug
About 1 in 256 aws login runs succeeds but leaves a cached token that every later command fails to load.
The login generates a P-256 DPoP key and stores it in the login cache as a SEC1 PEM. When the key's private scalar happens to start with a zero byte, awscrt on Linux exports it with a 31-byte privateKey instead of 32, and awscrt's own importer refuses a scalar that isn't exactly 32 bytes. The login itself works because it uses the key in memory, but everything after it reads the key from the cache and fails.
The root cause is in aws-c-cal, and I filed it there with a C repro and a patch: https://github.com/awslabs/aws-c-cal/issues/262. Filing here as well because this is where it shows up for users, and because the CLI turns it into a traceback.
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
A key written by aws login can be read back by the next command. If the cached key can't be loaded for any reason, I'd expect the "Unable to load private key from cached token" error instead of a traceback.
Current Behavior
After one login, every aws command using that profile failed like this until I ran aws login again:
File "awscli/botocore/credentials.py", line 2547, in refresh_credentials
File "awscli/botocore/credentials.py", line 2656, in _load_private_key
File "awscrt/crypto.py", line 279, in new_key_from_der_data
RuntimeError: 7178 (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT): Key format is not supported.
The dpopKey in the cache file decoded to this (values left out):
SEQUENCE len=118
INTEGER len=1 value=1
OCTET STRING len=31 <- privateKey, should be 32
[0] OID prime256v1
[1] BIT STRING len=66
Reproduction Steps
It takes a few hundred logins to hit by hand, so this does the same three calls as the CLI in a loop: generate the key (awscli/customizations/login/utils.py:70), export it as SEC1 (utils.py:202), and load it back (awscli/botocore/credentials.py:2656). Run it on Linux with the awscrt that the CLI pins (pip install awscrt==0.38.0 for 2.39.3):
from awscrt.crypto import EC, ECExportFormat, ECType
for i in range(1, 5001):
der = EC.new_generate(ECType.P_256).export_key(ECExportFormat.SEC1)
try:
EC.new_key_from_der_data(der)
except Exception as e:
# der[6] is the length of the privateKey OCTET STRING
print(f"key {i}: privateKey is {der[6]} bytes: {type(e).__name__}: {e}")
break
else:
print("no failure in 5000 keys")
Three runs:
key 99: privateKey is 31 bytes: RuntimeError: 7178 (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT): Key format is not supported.
key 142: privateKey is 31 bytes: RuntimeError: 7178 (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT): Key format is not supported.
key 737: privateKey is 31 bytes: RuntimeError: 7178 (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT): Key format is not supported.
On macOS the same loop doesn't fail (20,000 keys), because awscrt uses a different crypto backend there that always stores 32 bytes.
Possible Solution
The real fix is in aws-c-cal: pad the scalar on export, and accept a short one on import so caches already on disk become readable again. Details are in the issue linked above.
Two things I noticed on the CLI side (I haven't tried changing either):
-
_load_private_keycatchesValueError, but awscrt raisesRuntimeErrorfor a key it can't parse, so theLoginTokenLoadErrorpath is never taken: -
The DPoP key is new on every login, so the login could load the exported key once before writing the cache, and generate another if that fails. That would also cover CLI versions that ship before a fixed awscrt.
Additional Information/Context
Workaround: run aws login again. The next key almost certainly has a non-zero first byte.
2.40.0 pins awscrt 0.38.1, which bundles the same aws-c-cal commit as 0.38.0, so I expect it to behave the same, but I haven't run 2.40.0.
CLI version used
aws-cli/2.39.3 (awscrt 0.38.0, aws-c-cal v1.0.0)
Environment details (OS name and version, etc.)
The failed login was on Linux. The repro above ran on Debian 13 (arm64), Python 3.13.5, awscrt 0.38.0 from PyPI.
Generated by AI tools, and reviewed by Danny Lin.
- 主要语言
- Python
- 星标
- 17.4k
- 派生
- 4.8k
- 平均合并
- 4 天 3 小时
- 30 天内合并 PR
- 64
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
aws/aws-cli 的其他 Issue
-
bug needs-triage
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 2 天内回复
-
feature-request login p2
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 2 天内回复
-
aws history show/list: UnboundLocalError instead of clear error when pager fails to start可能已有人在做 @Adityaj0 于 85 天前认领。 未关闭needs-triage
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 2 天内回复
-
CodeArtifact login: auth token leaked unredacted in CommandFailedError via subprocess stderr可能已有人在做 @PANYAMHEMANTH 于 7 天前认领。 未关闭codeartifact login investigating p2
难度 2/5 1-3 小时 新手友好度 85/100
维护者通常 2 天内回复
-
Refactor: drop redundant list() wrapper around sorted() in formatter.py/text.py可能已有人在做 @Adityaj0 于 88 天前认领。 未关闭feature-request p3
难度 1/5 1 小时以内 新手友好度 90/100
维护者通常 2 天内回复
相似的 Issue
-
needs-triage
难度 2/5 1-3 小时 新手友好度 78/100
gke-labs/kube-agents#5671 ·
维护者通常 1 天内回复
-
documentation next-release v0.9.6
难度 1/5 1 小时以内 新手友好度 88/100
khuisman/mcp-gee-sweet#1446 ·
维护者通常 1 天内回复
-
model:sonnet runtime:claude security size:S
难度 2/5 1-3 小时 新手友好度 75/100
FootprintAI/Containarium#3671 ·
维护者通常 1 天内回复
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidays可能已有人在做 @shikhabhadoria 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
vacanza/holidays#4116 · 1 条评论 ·
维护者通常 1 天内回复
-
bug CLI exec
难度 2/5 1-3 小时 新手友好度 84/100
维护者通常 1 天内回复