Skip to content

Commit ace14e7

Browse files
authored
More support for PE flows, cleanup & improved typing (#70)
* Cleanup & improved typing * Disable odd policy enforcement * Add ".env-docker" file for local testing * Add PE test support (GHA and docker) (#71) * Add docker start script * Gemini fixes * Update GHA configuration * Gemini fixes * Enable PE e2e test * Run 'pre-commit autoupdate' & fix lint issues * Extract '_get_sdk_builder' function * Cleanup & remove redundant function * Improve typing * Use patch() context manager, reduce imports * Remove unnecessary import * Combine 'yq' expressions * Point to commit SHA * Remove hallucination * Match version number * Bump 0.3.0a5 to 0.3.0a6
1 parent 84cf5c1 commit ace14e7

28 files changed

+507
-371
lines changed

.env-docker

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
OPENTDF_PLATFORM_HOST="localhost"
2+
OPENTDF_PLATFORM_PORT=8080
3+
OPENTDF_PLATFORM_URL="http://localhost:8080"
4+
5+
KEYCLOAK_URL="http://localhost:8888/auth"
6+
OIDC_OP_TOKEN_ENDPOINT="http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token"

.github/start_opentdf_docker.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
if ! [ -d platform ]; then
6+
git clone https://github.com/opentdf/platform.git
7+
fi
8+
cd platform
9+
git checkout 3360befcb3e6e9791d7bfd2e89128aee0e7d2818 # Branch 'DSPX-1539-keytoolnomore'
10+
11+
yq -i '.realms[0].clients[0].client.directAccessGrantsEnabled = true | .realms[0].clients[0].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
12+
13+
yq -i '.realms[0].clients[1].client.directAccessGrantsEnabled = true | .realms[0].clients[1].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
14+
15+
yq -i '.realms[0].clients[4].client.directAccessGrantsEnabled = true | .realms[0].clients[4].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
16+
17+
18+
if ! [ -d ./keys ]; then
19+
go mod download
20+
21+
go mod verify
22+
23+
.github/scripts/init-temp-keys.sh
24+
cp opentdf-example.yaml opentdf.yaml
25+
26+
# Edit 'opentdf.yaml' for our use case
27+
yq -i 'del(.db) | .services.entityresolution.url = "http://localhost:8888/auth" | .server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
28+
# The above expression can also be written as 3 separate commands:
29+
# yq -i 'del(.db)' opentdf.yaml
30+
# yq -i '.services.entityresolution.url = "http://localhost:8888/auth"' opentdf.yaml
31+
# yq -i '.server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
32+
33+
yq -i '
34+
.server.cryptoProvider = {
35+
"type": "standard",
36+
"standard": {
37+
"keys": [
38+
{
39+
"kid": "r1",
40+
"alg": "rsa:2048",
41+
"private": "kas-private.pem",
42+
"cert": "kas-cert.pem"
43+
},
44+
{
45+
"kid": "e1",
46+
"alg": "ec:secp256r1",
47+
"private": "kas-ec-private.pem",
48+
"cert": "kas-ec-cert.pem"
49+
}
50+
]
51+
}
52+
}
53+
' opentdf.yaml
54+
chmod -R 700 ./keys
55+
fi
56+
57+
docker compose up -d --wait --wait-timeout 360
58+
59+
go run ./service provision keycloak
60+
61+
go run ./service provision fixtures

.github/workflows/platform-integration-test.yaml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,39 @@ jobs:
5555
shell: bash
5656
run: |
5757
.github/scripts/init-temp-keys.sh
58-
cp opentdf-dev.yaml opentdf.yaml
58+
# Edit Keycloak sample file for our use case
59+
yq -i '.realms[0].clients[0].client.directAccessGrantsEnabled = true | .realms[0].clients[0].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
60+
yq -i '.realms[0].clients[1].client.directAccessGrantsEnabled = true | .realms[0].clients[1].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
61+
yq -i '.realms[0].clients[4].client.directAccessGrantsEnabled = true | .realms[0].clients[4].client.serviceAccountsEnabled = true' service/cmd/keycloak_data.yaml
62+
63+
cp opentdf-example.yaml opentdf.yaml
64+
# Edit 'opentdf.yaml' for our use case
65+
yq -i 'del(.db) | .services.entityresolution.url = "http://localhost:8888/auth" | .server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
66+
# The above expression can also be written as 3 separate commands:
67+
# yq -i 'del(.db)' opentdf.yaml
68+
# yq -i '.services.entityresolution.url = "http://localhost:8888/auth"' opentdf.yaml
69+
# yq -i '.server.auth.issuer = "http://localhost:8888/auth/realms/opentdf"' opentdf.yaml
70+
yq -i '
71+
.server.cryptoProvider = {
72+
"type": "standard",
73+
"standard": {
74+
"keys": [
75+
{
76+
"kid": "r1",
77+
"alg": "rsa:2048",
78+
"private": "kas-private.pem",
79+
"cert": "kas-cert.pem"
80+
},
81+
{
82+
"kid": "e1",
83+
"alg": "ec:secp256r1",
84+
"private": "kas-ec-private.pem",
85+
"cert": "kas-ec-cert.pem"
86+
}
87+
]
88+
}
89+
}
90+
' opentdf.yaml
5991
sudo chmod -R 777 ./keys
6092
working-directory: platform
6193
# - name: Trust the locally issued cert

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Created by https://www.toptal.com/developers/gitignore/api/python
22
# Edit at https://www.toptal.com/developers/gitignore?templates=python
33

4+
platform/
5+
46
### Python ###
57
# Byte-compiled / optimized / DLL files
68
__pycache__/

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exclude: |
1212
# See https://pre-commit.com/hooks.html for more hooks#
1313
repos:
1414
- repo: https://github.com/pre-commit/pre-commit-hooks
15-
rev: v5.0.0
15+
rev: v6.0.0
1616
hooks:
1717
- id: check-yaml
1818
- id: end-of-file-fixer
@@ -45,7 +45,7 @@ repos:
4545

4646
- repo: https://github.com/astral-sh/ruff-pre-commit
4747
# Ruff version.
48-
rev: v0.12.8
48+
rev: v0.12.10
4949
hooks:
5050
# Run the linter.
5151
- id: ruff

otdf-python-proto/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "otdf-python-proto"
3-
version = "0.1.0"
3+
version = "0.3.0a6"
44
description = "Generated protobuf files for OpenTDF Python SDK"
55
readme = "README.md"
66
authors = [

otdf-python-proto/scripts/generate_connect_proto.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def check_dependencies() -> bool:
2626
try:
2727
subprocess.run(check_cmd, shell=True, capture_output=True, check=True)
2828
print(f"✓ {name} is available")
29-
except (subprocess.CalledProcessError, FileNotFoundError):
29+
except (subprocess.CalledProcessError, FileNotFoundError): # noqa: PERF203
3030
missing.append(name)
3131
print(f"✗ {name} is missing")
3232

@@ -104,7 +104,7 @@ def copy_opentdf_proto_files(proto_gen_dir: Path) -> bool:
104104

105105
copied_files += 1
106106

107-
except Exception as e:
107+
except Exception as e: # noqa: PERF203
108108
print(f" Warning: Failed to copy {relative_path}: {e}")
109109

110110
print(f"Found and copied {copied_files} proto files from repository")
@@ -235,7 +235,7 @@ def _fix_ignore_if_default_value(proto_files_dir):
235235

236236
print(f"Updated {proto_file.name} to use IGNORE_IF_ZERO_VALUE")
237237

238-
except Exception as e:
238+
except Exception as e: # noqa: PERF203
239239
print(f"Error updating {proto_file.name}: {e}")
240240

241241

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "otdf-python"
3-
version = "0.3.0a5"
3+
version = "0.3.0a6"
44
description = "Unofficial OpenTDF SDK for Python"
55
readme = "README.md"
66
authors = [

src/otdf_python/cli.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
OpenTDF Python CLI
44
55
A command-line interface for encrypting and decrypting files using OpenTDF.
6-
Provides encrypt, decrypt, and inspect commands similar to the TypeScript CLI.
6+
Provides encrypt, decrypt, and inspect commands similar to the otdfctl CLI.
77
"""
88

99
import argparse
@@ -22,7 +22,7 @@
2222

2323

2424
# Version - get from project metadata
25-
__version__ = "0.3.0a5"
25+
__version__ = "0.3.0a6"
2626

2727

2828
# Set up logging
@@ -146,7 +146,7 @@ def build_sdk(args) -> SDK:
146146
else:
147147
raise CLIError(
148148
"CRITICAL",
149-
"Authentication required: provide --with-client-creds-file, --client-id and --client-secret, or --auth",
149+
"Authentication required: provide --with-client-creds-file OR --client-id and --client-secret",
150150
)
151151

152152
if hasattr(args, "plaintext") and args.plaintext:
@@ -307,7 +307,9 @@ def cmd_decrypt(args):
307307
# Regular TDF (ZIP format)
308308
logger.debug("Decrypting TDF")
309309
reader_config = TDFReaderConfig()
310-
tdf_reader = sdk.load_tdf(encrypted_data, reader_config)
310+
tdf_reader = sdk.load_tdf_with_config(
311+
encrypted_data, reader_config
312+
)
311313
# Access payload directly from TDFReader
312314
payload_bytes = tdf_reader.payload
313315
output_file.write(payload_bytes)
@@ -331,7 +333,7 @@ def cmd_decrypt(args):
331333
# Regular TDF (ZIP format)
332334
logger.debug("Decrypting TDF")
333335
reader_config = TDFReaderConfig()
334-
tdf_reader = sdk.load_tdf(encrypted_data, reader_config)
336+
tdf_reader = sdk.load_tdf_with_config(encrypted_data, reader_config)
335337
payload_bytes = tdf_reader.payload
336338
output_file.write(payload_bytes)
337339
logger.info("Successfully decrypted TDF")
@@ -384,7 +386,9 @@ def cmd_inspect(args):
384386
# Regular TDF
385387
logger.debug("Inspecting TDF")
386388
reader_config = TDFReaderConfig()
387-
tdf_reader = sdk.load_tdf(BytesIO(encrypted_data), reader_config)
389+
tdf_reader = sdk.load_tdf_with_config(
390+
BytesIO(encrypted_data), reader_config
391+
)
388392
manifest = tdf_reader.manifest
389393

390394
# Try to get data attributes
@@ -479,11 +483,6 @@ def create_parser() -> argparse.ArgumentParser:
479483
)
480484
auth_group.add_argument("--client-id", help="OAuth client ID")
481485
auth_group.add_argument("--client-secret", help="OAuth client secret")
482-
# Keep --auth for backward compatibility
483-
auth_group.add_argument(
484-
"--auth",
485-
help="Combined OAuth credentials (clientId:clientSecret) - deprecated, use --with-client-creds-file",
486-
)
487486

488487
# Security options
489488
security_group = parser.add_argument_group("Security")

src/otdf_python/crypto_utils.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,3 @@ def get_rsa_private_key_from_pem(pem_data: str) -> rsa.RSAPrivateKey:
7575
if not isinstance(private_key, rsa.RSAPrivateKey):
7676
raise ValueError("Not an RSA private key")
7777
return private_key
78-
79-
80-
# Aliases for compatibility
81-
rsa_private_key_from_pem = CryptoUtils.get_rsa_private_key_from_pem
82-
rsa_public_key_from_pem = CryptoUtils.get_rsa_public_key_from_pem

0 commit comments

Comments
 (0)