Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/id/__init__.py: 52%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright 2022 The Sigstore Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""
16API for retrieving OIDC tokens.
17"""
19from __future__ import annotations
21import base64
22from typing import Callable
24__version__ = "1.5.0"
27class IdentityError(Exception):
28 """
29 Raised on any OIDC token format or claim error.
30 """
32 pass
35class AmbientCredentialError(IdentityError):
36 """
37 Raised when an ambient credential should be present, but
38 can't be retrieved (e.g. network failure).
39 """
41 pass
44class GitHubOidcPermissionCredentialError(AmbientCredentialError):
45 """
46 Raised when the current GitHub Actions environment doesn't have permission
47 to retrieve an OIDC token.
48 """
50 pass
53def detect_credential(audience: str) -> str | None:
54 """
55 Try each ambient credential detector, returning the first one to succeed
56 or `None` if all fail.
58 Raises `AmbientCredentialError` if any detector fails internally (i.e.
59 detects a credential, but cannot retrieve it).
60 """
61 from ._internal.oidc.ambient import (
62 detect_buildkite,
63 detect_circleci,
64 detect_gcp,
65 detect_github,
66 detect_gitlab,
67 )
69 detectors: list[Callable[..., str | None]] = [
70 detect_github,
71 detect_gcp,
72 detect_buildkite,
73 detect_gitlab,
74 detect_circleci,
75 ]
76 for detector in detectors:
77 credential = detector(audience)
78 if credential is not None:
79 return credential
80 return None
83def decode_oidc_token(token: str) -> tuple[str, str, str]:
84 # Split the token into its three parts: header, payload, and signature
85 header, payload, signature = token.split(".")
87 # Decode base64-encoded header and payload
88 decoded_header = base64.urlsafe_b64decode(header + "==").decode("utf-8")
89 decoded_payload = base64.urlsafe_b64decode(payload + "==").decode("utf-8")
91 return decoded_header, decoded_payload, signature