tba-concrete-authorization-provenance 0.4.0.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tba_concrete_authorization_provenance-0.4.0.dev2/PKG-INFO +15 -0
- tba_concrete_authorization_provenance-0.4.0.dev2/pyproject.toml +14 -0
- tba_concrete_authorization_provenance-0.4.0.dev2/src/tba_concrete_authorization_provenance/__init__.py +155 -0
- tba_concrete_authorization_provenance-0.4.0.dev2/src/tba_concrete_authorization_provenance/py.typed +1 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tba-concrete-authorization-provenance
|
|
3
|
+
Version: 0.4.0.dev2
|
|
4
|
+
Summary: Deterministic authorization and delegation provenance builders.
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.10,<3.15
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: tba-bases-security-provenance (==0.1.0)
|
|
14
|
+
Requires-Dist: tba-contracts-security-trust (==0.1.0)
|
|
15
|
+
Requires-Dist: tba-primitives-identity (==0.4.0.dev2)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "tba-concrete-authorization-provenance"
|
|
3
|
+
version = "0.4.0.dev2"
|
|
4
|
+
description = "Deterministic authorization and delegation provenance builders."
|
|
5
|
+
requires-python = ">=3.10,<3.15"
|
|
6
|
+
license = "Apache-2.0"
|
|
7
|
+
dependencies = ["tba-primitives-identity==0.4.0.dev2", "tba-bases-security-provenance==0.1.0", "tba-contracts-security-trust==0.1.0"]
|
|
8
|
+
|
|
9
|
+
[build-system]
|
|
10
|
+
requires = ["poetry-core>=1.0.0"]
|
|
11
|
+
build-backend = "poetry.core.masonry.api"
|
|
12
|
+
|
|
13
|
+
[tool.poetry]
|
|
14
|
+
packages = [{ include = "tba_concrete_authorization_provenance", from = "src" }]
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Mapping
|
|
4
|
+
|
|
5
|
+
from tba_primitives_identity.json_canonicalization import canonical_hash, canonical_json
|
|
6
|
+
from tba_bases_security_provenance import ProvenanceArtifactBuilderBase
|
|
7
|
+
from tba_contracts_security_trust import (
|
|
8
|
+
AuthorizationDecisionTrace,
|
|
9
|
+
CapabilityMap,
|
|
10
|
+
DelegationProvenance,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def build_authorization_decision_trace(
|
|
15
|
+
*,
|
|
16
|
+
tenant_id: str | None,
|
|
17
|
+
subject: str,
|
|
18
|
+
issuer: str,
|
|
19
|
+
audience: str | list[str] | None,
|
|
20
|
+
resource: str | None,
|
|
21
|
+
scope: str | None,
|
|
22
|
+
subject_token_type: str,
|
|
23
|
+
requested_token_type: str,
|
|
24
|
+
exchange_mode: str,
|
|
25
|
+
actor_subject: str | None,
|
|
26
|
+
source_issuer: str | None,
|
|
27
|
+
sender_constraint: str,
|
|
28
|
+
verifier_logic_id: str | None = None,
|
|
29
|
+
required_claims: tuple[str, ...] = (),
|
|
30
|
+
) -> dict[str, Any]:
|
|
31
|
+
request_view = {
|
|
32
|
+
"tenant_id": tenant_id or "",
|
|
33
|
+
"subject": subject,
|
|
34
|
+
"issuer": issuer,
|
|
35
|
+
"audience": audience,
|
|
36
|
+
"resource": resource,
|
|
37
|
+
"scope": scope or "",
|
|
38
|
+
"subject_token_type": subject_token_type,
|
|
39
|
+
"requested_token_type": requested_token_type,
|
|
40
|
+
"exchange_mode": exchange_mode,
|
|
41
|
+
"actor_subject": actor_subject or "",
|
|
42
|
+
"source_issuer": source_issuer or "",
|
|
43
|
+
"sender_constraint": sender_constraint,
|
|
44
|
+
}
|
|
45
|
+
derived_grant = {
|
|
46
|
+
"issuer": issuer,
|
|
47
|
+
"audience": audience,
|
|
48
|
+
"resource": resource,
|
|
49
|
+
"scope": scope or "",
|
|
50
|
+
"token_kind": "access",
|
|
51
|
+
"requested_token_type": requested_token_type,
|
|
52
|
+
"exchange_mode": exchange_mode,
|
|
53
|
+
"actor_subject": actor_subject or "",
|
|
54
|
+
}
|
|
55
|
+
policy_view = {
|
|
56
|
+
"verifier_logic_id": verifier_logic_id or "default-protected-resource-verifier",
|
|
57
|
+
"required_claims": list(required_claims),
|
|
58
|
+
"sender_constraint": sender_constraint,
|
|
59
|
+
"resource": resource,
|
|
60
|
+
"audience": audience,
|
|
61
|
+
}
|
|
62
|
+
request_hash = canonical_hash(request_view)
|
|
63
|
+
policy_hash = canonical_hash(policy_view)
|
|
64
|
+
derivation_hash = canonical_hash(derived_grant)
|
|
65
|
+
trace = AuthorizationDecisionTrace(
|
|
66
|
+
request_hash=request_hash,
|
|
67
|
+
policy_hash=policy_hash,
|
|
68
|
+
derivation_hash=derivation_hash,
|
|
69
|
+
decision_key=canonical_hash(
|
|
70
|
+
{
|
|
71
|
+
"request_hash": request_hash,
|
|
72
|
+
"policy_hash": policy_hash,
|
|
73
|
+
"derivation_hash": derivation_hash,
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
request=request_view,
|
|
77
|
+
derived_grant=derived_grant,
|
|
78
|
+
)
|
|
79
|
+
return trace.as_dict()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def build_delegation_provenance(
|
|
83
|
+
*,
|
|
84
|
+
subject_token: str,
|
|
85
|
+
actor_token: str | None,
|
|
86
|
+
subject_claims: Mapping[str, Any],
|
|
87
|
+
actor_claims: Mapping[str, Any] | None,
|
|
88
|
+
authorization_trace: Mapping[str, Any],
|
|
89
|
+
audience: str | list[str] | None,
|
|
90
|
+
resource: str | None,
|
|
91
|
+
exchange_mode: str,
|
|
92
|
+
sender_constraint: str,
|
|
93
|
+
) -> dict[str, Any]:
|
|
94
|
+
subject_token_hash = canonical_hash({"token": subject_token})
|
|
95
|
+
actor_token_hash = canonical_hash({"token": actor_token}) if actor_token else None
|
|
96
|
+
nodes = {
|
|
97
|
+
"subject": {
|
|
98
|
+
"sub": str(subject_claims.get("sub") or ""),
|
|
99
|
+
"iss": str(subject_claims.get("iss") or ""),
|
|
100
|
+
"aud": subject_claims.get("aud"),
|
|
101
|
+
},
|
|
102
|
+
"actor": {
|
|
103
|
+
"sub": str((actor_claims or {}).get("sub") or ""),
|
|
104
|
+
"iss": str((actor_claims or {}).get("iss") or ""),
|
|
105
|
+
}
|
|
106
|
+
if actor_claims
|
|
107
|
+
else None,
|
|
108
|
+
}
|
|
109
|
+
edge = {
|
|
110
|
+
"exchange_mode": exchange_mode,
|
|
111
|
+
"audience": audience,
|
|
112
|
+
"resource": resource,
|
|
113
|
+
"sender_constraint": sender_constraint,
|
|
114
|
+
"decision_key": authorization_trace.get("decision_key"),
|
|
115
|
+
"subject_token_hash": subject_token_hash,
|
|
116
|
+
"actor_token_hash": actor_token_hash,
|
|
117
|
+
}
|
|
118
|
+
provenance = DelegationProvenance(
|
|
119
|
+
lineage_id=canonical_hash({"nodes": nodes, "edge": edge}),
|
|
120
|
+
subject_token_hash=subject_token_hash,
|
|
121
|
+
actor_token_hash=actor_token_hash,
|
|
122
|
+
nodes=nodes,
|
|
123
|
+
edge=edge,
|
|
124
|
+
)
|
|
125
|
+
return provenance.as_dict()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class DeterministicProvenanceArtifactBuilder(ProvenanceArtifactBuilderBase):
|
|
129
|
+
"""Build authorization and delegation provenance without environmental I/O."""
|
|
130
|
+
|
|
131
|
+
def supports(self) -> CapabilityMap:
|
|
132
|
+
return CapabilityMap(
|
|
133
|
+
ops={
|
|
134
|
+
"build_authorization_decision_trace": ("deterministic",),
|
|
135
|
+
"build_delegation_provenance": ("deterministic",),
|
|
136
|
+
},
|
|
137
|
+
features=("authorization-provenance", "delegation-lineage"),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def build_authorization_decision_trace(self, **kwargs: Any) -> dict[str, Any]:
|
|
141
|
+
return build_authorization_decision_trace(**kwargs)
|
|
142
|
+
|
|
143
|
+
def build_delegation_provenance(self, **kwargs: Any) -> dict[str, Any]:
|
|
144
|
+
return build_delegation_provenance(**kwargs)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
__all__ = [
|
|
148
|
+
"AuthorizationDecisionTrace",
|
|
149
|
+
"DelegationProvenance",
|
|
150
|
+
"DeterministicProvenanceArtifactBuilder",
|
|
151
|
+
"build_authorization_decision_trace",
|
|
152
|
+
"build_delegation_provenance",
|
|
153
|
+
"canonical_hash",
|
|
154
|
+
"canonical_json",
|
|
155
|
+
]
|