ceramic-fwk 0.1.2__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.
- ceramic_fwk-0.1.2/.codegraph/.gitignore +5 -0
- ceramic_fwk-0.1.2/.github/ISSUE_TEMPLATE/architecture_proposal.md +74 -0
- ceramic_fwk-0.1.2/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- ceramic_fwk-0.1.2/.github/ISSUE_TEMPLATE/feature_request.md +48 -0
- ceramic_fwk-0.1.2/.github/PULL_REQUEST_TEMPLATE.md +63 -0
- ceramic_fwk-0.1.2/.github/workflows/ci.yml +51 -0
- ceramic_fwk-0.1.2/.github/workflows/pages.yml +37 -0
- ceramic_fwk-0.1.2/.github/workflows/publish.yml +86 -0
- ceramic_fwk-0.1.2/.github/workflows/release.yml +75 -0
- ceramic_fwk-0.1.2/.github/workflows/security.yml +85 -0
- ceramic_fwk-0.1.2/.github/workflows/test.yml +77 -0
- ceramic_fwk-0.1.2/.gitignore +36 -0
- ceramic_fwk-0.1.2/.kiro/specs/ceramic-framework/.config.kiro +1 -0
- ceramic_fwk-0.1.2/.kiro/specs/ceramic-framework/design.md +790 -0
- ceramic_fwk-0.1.2/.kiro/specs/ceramic-framework/requirements.md +202 -0
- ceramic_fwk-0.1.2/.kiro/specs/ceramic-framework/tasks.md +328 -0
- ceramic_fwk-0.1.2/.kiro/specs/idp-resilience-and-adapters/.config.kiro +1 -0
- ceramic_fwk-0.1.2/.kiro/specs/idp-resilience-and-adapters/design.md +853 -0
- ceramic_fwk-0.1.2/.kiro/specs/idp-resilience-and-adapters/requirements.md +132 -0
- ceramic_fwk-0.1.2/.kiro/specs/idp-resilience-and-adapters/tasks.md +61 -0
- ceramic_fwk-0.1.2/.kiro/steering/readme-sync.md +35 -0
- ceramic_fwk-0.1.2/CHANGELOG.md +51 -0
- ceramic_fwk-0.1.2/CONTRIBUTING.md +119 -0
- ceramic_fwk-0.1.2/LICENSE +191 -0
- ceramic_fwk-0.1.2/PKG-INFO +898 -0
- ceramic_fwk-0.1.2/README.md +847 -0
- ceramic_fwk-0.1.2/SECURITY.md +46 -0
- ceramic_fwk-0.1.2/ceramic/__init__.py +25 -0
- ceramic_fwk-0.1.2/ceramic/auth/__init__.py +6 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/__init__.py +26 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/base.py +50 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/entra.py +107 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/google.py +92 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/registry.py +45 -0
- ceramic_fwk-0.1.2/ceramic/auth/adapters/rfc8693.py +55 -0
- ceramic_fwk-0.1.2/ceramic/auth/callback_server.py +140 -0
- ceramic_fwk-0.1.2/ceramic/auth/claims.py +104 -0
- ceramic_fwk-0.1.2/ceramic/auth/jwks_manager.py +335 -0
- ceramic_fwk-0.1.2/ceramic/auth/oauth.py +450 -0
- ceramic_fwk-0.1.2/ceramic/auth/token_storage.py +297 -0
- ceramic_fwk-0.1.2/ceramic/cli/__init__.py +328 -0
- ceramic_fwk-0.1.2/ceramic/config.py +144 -0
- ceramic_fwk-0.1.2/ceramic/config_loader.py +372 -0
- ceramic_fwk-0.1.2/ceramic/downstream.py +265 -0
- ceramic_fwk-0.1.2/ceramic/exceptions.py +27 -0
- ceramic_fwk-0.1.2/ceramic/identity.py +82 -0
- ceramic_fwk-0.1.2/ceramic/metrics.py +123 -0
- ceramic_fwk-0.1.2/ceramic/middleware/__init__.py +25 -0
- ceramic_fwk-0.1.2/ceramic/middleware/authentication.py +425 -0
- ceramic_fwk-0.1.2/ceramic/middleware/builtin.py +93 -0
- ceramic_fwk-0.1.2/ceramic/middleware/observability.py +145 -0
- ceramic_fwk-0.1.2/ceramic/middleware/pipeline.py +252 -0
- ceramic_fwk-0.1.2/ceramic/middleware/session.py +125 -0
- ceramic_fwk-0.1.2/ceramic/models.py +59 -0
- ceramic_fwk-0.1.2/ceramic/observability.py +272 -0
- ceramic_fwk-0.1.2/ceramic/resilience.py +299 -0
- ceramic_fwk-0.1.2/ceramic/security.py +153 -0
- ceramic_fwk-0.1.2/ceramic/server.py +477 -0
- ceramic_fwk-0.1.2/ceramic/sessions.py +89 -0
- ceramic_fwk-0.1.2/ceramic/testing/__init__.py +272 -0
- ceramic_fwk-0.1.2/ceramic.yaml.example +55 -0
- ceramic_fwk-0.1.2/docs/GUIDE.md +1064 -0
- ceramic_fwk-0.1.2/docs/demo.gif +0 -0
- ceramic_fwk-0.1.2/docs/demo.tape +68 -0
- ceramic_fwk-0.1.2/docs/index.html +1000 -0
- ceramic_fwk-0.1.2/docs/logo.svg +10 -0
- ceramic_fwk-0.1.2/examples/auth_server.py +46 -0
- ceramic_fwk-0.1.2/examples/basic_server.py +27 -0
- ceramic_fwk-0.1.2/examples/headless_ceramic.yaml +36 -0
- ceramic_fwk-0.1.2/examples/headless_server.py +140 -0
- ceramic_fwk-0.1.2/examples/migration_example.py +36 -0
- ceramic_fwk-0.1.2/examples/testing_example.py +53 -0
- ceramic_fwk-0.1.2/examples/zitadel/README.md +154 -0
- ceramic_fwk-0.1.2/examples/zitadel/ceramic.yaml +28 -0
- ceramic_fwk-0.1.2/examples/zitadel/mcp_client.py +264 -0
- ceramic_fwk-0.1.2/examples/zitadel/petstore_server.py +207 -0
- ceramic_fwk-0.1.2/examples/zitadel/server.py +237 -0
- ceramic_fwk-0.1.2/examples/zitadel/test_server.py +193 -0
- ceramic_fwk-0.1.2/pyproject.toml +75 -0
- ceramic_fwk-0.1.2/scripts/_setup.sh +40 -0
- ceramic_fwk-0.1.2/scripts/demo-headless.sh +307 -0
- ceramic_fwk-0.1.2/scripts/demo.sh +155 -0
- ceramic_fwk-0.1.2/scripts/record-demo.sh +107 -0
- ceramic_fwk-0.1.2/scripts/release.sh +93 -0
- ceramic_fwk-0.1.2/tests/__init__.py +0 -0
- ceramic_fwk-0.1.2/tests/conftest.py +1 -0
- ceramic_fwk-0.1.2/tests/integration/__init__.py +0 -0
- ceramic_fwk-0.1.2/tests/integration/test_e2e_auth_flow.py +126 -0
- ceramic_fwk-0.1.2/tests/integration/test_pipeline_flow.py +96 -0
- ceramic_fwk-0.1.2/tests/properties/__init__.py +0 -0
- ceramic_fwk-0.1.2/tests/properties/test_circuit_breaker_properties.py +108 -0
- ceramic_fwk-0.1.2/tests/properties/test_circuit_breaker_props.py +162 -0
- ceramic_fwk-0.1.2/tests/properties/test_log_redactor_properties.py +114 -0
- ceramic_fwk-0.1.2/tests/properties/test_tls_enforcer_properties.py +47 -0
- ceramic_fwk-0.1.2/tests/unit/__init__.py +0 -0
- ceramic_fwk-0.1.2/tests/unit/test_adapters.py +265 -0
- ceramic_fwk-0.1.2/tests/unit/test_authentication_middleware.py +524 -0
- ceramic_fwk-0.1.2/tests/unit/test_cli.py +466 -0
- ceramic_fwk-0.1.2/tests/unit/test_config_loader.py +254 -0
- ceramic_fwk-0.1.2/tests/unit/test_config_models.py +49 -0
- ceramic_fwk-0.1.2/tests/unit/test_exceptions.py +46 -0
- ceramic_fwk-0.1.2/tests/unit/test_hot_reload.py +342 -0
- ceramic_fwk-0.1.2/tests/unit/test_identity.py +85 -0
- ceramic_fwk-0.1.2/tests/unit/test_identity_propagation.py +342 -0
- ceramic_fwk-0.1.2/tests/unit/test_log_redactor.py +110 -0
- ceramic_fwk-0.1.2/tests/unit/test_metrics_exporter.py +188 -0
- ceramic_fwk-0.1.2/tests/unit/test_middleware_pipeline.py +337 -0
- ceramic_fwk-0.1.2/tests/unit/test_models.py +112 -0
- ceramic_fwk-0.1.2/tests/unit/test_oauth_resilient_integration.py +398 -0
- ceramic_fwk-0.1.2/tests/unit/test_oauth_service.py +364 -0
- ceramic_fwk-0.1.2/tests/unit/test_observability.py +177 -0
- ceramic_fwk-0.1.2/tests/unit/test_pipeline_wiring.py +289 -0
- ceramic_fwk-0.1.2/tests/unit/test_public_api.py +51 -0
- ceramic_fwk-0.1.2/tests/unit/test_server.py +237 -0
- ceramic_fwk-0.1.2/tests/unit/test_session_middleware.py +158 -0
- ceramic_fwk-0.1.2/tests/unit/test_session_store.py +185 -0
- ceramic_fwk-0.1.2/tests/unit/test_testing_utilities.py +270 -0
- ceramic_fwk-0.1.2/tests/unit/test_tls_enforcer.py +72 -0
- ceramic_fwk-0.1.2/tests/unit/test_token_storage.py +347 -0
- ceramic_fwk-0.1.2/uv.lock +1769 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Architecture Proposal
|
|
3
|
+
about: Propose a significant architectural change requiring an ADR
|
|
4
|
+
title: "[Architecture] "
|
|
5
|
+
labels: architecture
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
One-paragraph description of the proposed change.
|
|
12
|
+
|
|
13
|
+
## Motivation
|
|
14
|
+
|
|
15
|
+
Why is this change needed? What problem does it solve?
|
|
16
|
+
|
|
17
|
+
## Current Architecture
|
|
18
|
+
|
|
19
|
+
How does the relevant part of the system work today?
|
|
20
|
+
|
|
21
|
+
## Proposed Architecture
|
|
22
|
+
|
|
23
|
+
How should it work after this change?
|
|
24
|
+
|
|
25
|
+
## Design Details
|
|
26
|
+
|
|
27
|
+
### Components Affected
|
|
28
|
+
|
|
29
|
+
- [ ] `ceramic/server.py` (CeramicFastMCP)
|
|
30
|
+
- [ ] `ceramic/middleware/` (pipeline)
|
|
31
|
+
- [ ] `ceramic/auth/` (OAuth/OIDC)
|
|
32
|
+
- [ ] `ceramic/config.py` (configuration models)
|
|
33
|
+
- [ ] `ceramic/identity.py` (identity propagation)
|
|
34
|
+
- [ ] `ceramic/resilience.py` (circuit breaker)
|
|
35
|
+
- [ ] `ceramic/security.py` (TLS/redaction)
|
|
36
|
+
- [ ] Public API (`ceramic/__init__.py`)
|
|
37
|
+
- [ ] Other:
|
|
38
|
+
|
|
39
|
+
### Migration Path
|
|
40
|
+
|
|
41
|
+
How do existing users migrate? Is it backward compatible?
|
|
42
|
+
|
|
43
|
+
### Security Impact
|
|
44
|
+
|
|
45
|
+
Does this change affect authentication, authorization, or data protection?
|
|
46
|
+
|
|
47
|
+
## ADR Draft
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# ADR-XXX: [Title]
|
|
51
|
+
|
|
52
|
+
## Status
|
|
53
|
+
Proposed
|
|
54
|
+
|
|
55
|
+
## Context
|
|
56
|
+
[Why this decision is needed]
|
|
57
|
+
|
|
58
|
+
## Decision
|
|
59
|
+
[What was decided]
|
|
60
|
+
|
|
61
|
+
## Rationale
|
|
62
|
+
[Why this approach over alternatives]
|
|
63
|
+
|
|
64
|
+
## Consequences
|
|
65
|
+
[Positive and negative effects]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Risks
|
|
69
|
+
|
|
70
|
+
What could go wrong? How do we mitigate it?
|
|
71
|
+
|
|
72
|
+
## Alternatives Rejected
|
|
73
|
+
|
|
74
|
+
Other approaches considered and why they don't fit.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug in Ceramic
|
|
4
|
+
title: "[Bug] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
A clear description of the bug.
|
|
12
|
+
|
|
13
|
+
## Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1.
|
|
16
|
+
2.
|
|
17
|
+
3.
|
|
18
|
+
|
|
19
|
+
## Expected Behavior
|
|
20
|
+
|
|
21
|
+
What you expected to happen.
|
|
22
|
+
|
|
23
|
+
## Actual Behavior
|
|
24
|
+
|
|
25
|
+
What actually happened. Include error messages or stack traces if available.
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- **Python version**:
|
|
30
|
+
- **Ceramic version**:
|
|
31
|
+
- **OS**:
|
|
32
|
+
- **FastMCP version**:
|
|
33
|
+
- **Identity Provider** (if auth-related):
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
Relevant `ceramic.yaml` sections (redact secrets):
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Minimal Reproducing Example
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Additional Context
|
|
50
|
+
|
|
51
|
+
Any other relevant information (logs, screenshots, related issues).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Propose a new feature for Ceramic
|
|
4
|
+
title: "[Feature] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
What problem does this solve? Who needs it?
|
|
12
|
+
|
|
13
|
+
## Proposed Solution
|
|
14
|
+
|
|
15
|
+
Describe the feature you'd like.
|
|
16
|
+
|
|
17
|
+
## Configuration (if applicable)
|
|
18
|
+
|
|
19
|
+
How would this be configured in `ceramic.yaml`?
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API (if applicable)
|
|
26
|
+
|
|
27
|
+
How would users interact with this feature in code?
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Alternatives Considered
|
|
34
|
+
|
|
35
|
+
Other approaches you've considered and why they don't fit.
|
|
36
|
+
|
|
37
|
+
## Design Considerations
|
|
38
|
+
|
|
39
|
+
- Does this affect the public API?
|
|
40
|
+
- Does this require a new ADR?
|
|
41
|
+
- Are there security implications?
|
|
42
|
+
- Does this need a new dependency?
|
|
43
|
+
|
|
44
|
+
## Acceptance Criteria
|
|
45
|
+
|
|
46
|
+
- [ ]
|
|
47
|
+
- [ ]
|
|
48
|
+
- [ ]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
Brief description of what this PR does.
|
|
4
|
+
|
|
5
|
+
## Type of Change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (non-breaking change that fixes an issue)
|
|
8
|
+
- [ ] New feature (non-breaking change that adds functionality)
|
|
9
|
+
- [ ] Breaking change (fix or feature that changes existing behavior)
|
|
10
|
+
- [ ] Documentation update
|
|
11
|
+
- [ ] Refactoring (no functional change)
|
|
12
|
+
- [ ] CI/CD or tooling change
|
|
13
|
+
|
|
14
|
+
## Related Issues
|
|
15
|
+
|
|
16
|
+
Closes #
|
|
17
|
+
|
|
18
|
+
## Changes
|
|
19
|
+
|
|
20
|
+
-
|
|
21
|
+
-
|
|
22
|
+
-
|
|
23
|
+
|
|
24
|
+
## How to Test
|
|
25
|
+
|
|
26
|
+
Steps to verify this change:
|
|
27
|
+
|
|
28
|
+
1.
|
|
29
|
+
2.
|
|
30
|
+
3.
|
|
31
|
+
|
|
32
|
+
## Checklist
|
|
33
|
+
|
|
34
|
+
### General
|
|
35
|
+
- [ ] Code follows the project style (ruff check + ruff format pass)
|
|
36
|
+
- [ ] Type annotations on all new public functions
|
|
37
|
+
- [ ] Docstrings on all new public classes/functions
|
|
38
|
+
- [ ] CHANGELOG.md updated under `[Unreleased]` (if user-facing)
|
|
39
|
+
|
|
40
|
+
### Testing
|
|
41
|
+
- [ ] Unit tests added/updated
|
|
42
|
+
- [ ] Property-based tests added (if security-sensitive)
|
|
43
|
+
- [ ] All tests pass (`pytest -v`)
|
|
44
|
+
- [ ] No real HTTP calls in tests (mocked or test utilities used)
|
|
45
|
+
|
|
46
|
+
### Security (if touching auth, tokens, or IDP communication)
|
|
47
|
+
- [ ] Read `.ai/security.md` before making changes
|
|
48
|
+
- [ ] No tokens/secrets logged
|
|
49
|
+
- [ ] TLS enforcement preserved
|
|
50
|
+
- [ ] Circuit breaker protection preserved
|
|
51
|
+
- [ ] Relevant ADR read and respected
|
|
52
|
+
|
|
53
|
+
### Architecture
|
|
54
|
+
- [ ] Public API (`ceramic/__init__.py`) unchanged (or ADR written)
|
|
55
|
+
- [ ] Middleware execution order preserved
|
|
56
|
+
- [ ] No new dependencies without justification in PR description
|
|
57
|
+
- [ ] Configuration changes have defaults (backward compatible)
|
|
58
|
+
|
|
59
|
+
## Screenshots / Logs (if applicable)
|
|
60
|
+
|
|
61
|
+
## Additional Notes
|
|
62
|
+
|
|
63
|
+
Anything reviewers should know.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, "release/**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: pytest -v --tb=short
|
|
28
|
+
|
|
29
|
+
- name: Run property-based tests with extended examples
|
|
30
|
+
run: pytest tests/properties/ -v --hypothesis-seed=0
|
|
31
|
+
|
|
32
|
+
lint:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- uses: actions/setup-python@v5
|
|
38
|
+
with:
|
|
39
|
+
python-version: "3.12"
|
|
40
|
+
|
|
41
|
+
- name: Install dev dependencies
|
|
42
|
+
run: pip install -e ".[dev]" ruff mypy
|
|
43
|
+
|
|
44
|
+
- name: Ruff check
|
|
45
|
+
run: ruff check ceramic/ tests/
|
|
46
|
+
|
|
47
|
+
- name: Ruff format check
|
|
48
|
+
run: ruff format --check ceramic/ tests/
|
|
49
|
+
|
|
50
|
+
- name: Type check
|
|
51
|
+
run: mypy ceramic/ --ignore-missing-imports
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Deploy Landing Page
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: pages
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
deploy:
|
|
20
|
+
environment:
|
|
21
|
+
name: github-pages
|
|
22
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Setup Pages
|
|
28
|
+
uses: actions/configure-pages@v4
|
|
29
|
+
|
|
30
|
+
- name: Upload artifact
|
|
31
|
+
uses: actions/upload-pages-artifact@v3
|
|
32
|
+
with:
|
|
33
|
+
path: docs/
|
|
34
|
+
|
|
35
|
+
- name: Deploy to GitHub Pages
|
|
36
|
+
id: deployment
|
|
37
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: pip install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Run tests
|
|
28
|
+
run: pytest -v --tb=short
|
|
29
|
+
|
|
30
|
+
build:
|
|
31
|
+
needs: test
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.12"
|
|
39
|
+
|
|
40
|
+
- name: Install build tools
|
|
41
|
+
run: pip install build
|
|
42
|
+
|
|
43
|
+
- name: Build package
|
|
44
|
+
run: python -m build
|
|
45
|
+
|
|
46
|
+
- name: Upload artifacts
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
|
|
52
|
+
publish:
|
|
53
|
+
needs: build
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
environment: pypi
|
|
56
|
+
permissions:
|
|
57
|
+
id-token: write
|
|
58
|
+
steps:
|
|
59
|
+
- name: Download artifacts
|
|
60
|
+
uses: actions/download-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: dist
|
|
63
|
+
path: dist/
|
|
64
|
+
|
|
65
|
+
- name: Publish to PyPI
|
|
66
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
67
|
+
|
|
68
|
+
github-release:
|
|
69
|
+
needs: publish
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
permissions:
|
|
72
|
+
contents: write
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
|
|
76
|
+
- name: Download artifacts
|
|
77
|
+
uses: actions/download-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: dist
|
|
80
|
+
path: dist/
|
|
81
|
+
|
|
82
|
+
- name: Create GitHub Release
|
|
83
|
+
uses: softprops/action-gh-release@v2
|
|
84
|
+
with:
|
|
85
|
+
generate_release_notes: true
|
|
86
|
+
files: dist/*
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
bump:
|
|
7
|
+
description: "Version bump type"
|
|
8
|
+
required: false
|
|
9
|
+
default: "patch"
|
|
10
|
+
type: choice
|
|
11
|
+
options:
|
|
12
|
+
- patch
|
|
13
|
+
- minor
|
|
14
|
+
- major
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: write
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
release:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
|
|
28
|
+
- name: Configure git
|
|
29
|
+
run: |
|
|
30
|
+
git config user.name "github-actions[bot]"
|
|
31
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
32
|
+
|
|
33
|
+
- name: Get current version
|
|
34
|
+
id: current
|
|
35
|
+
run: |
|
|
36
|
+
VERSION=$(grep '^version' pyproject.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
|
37
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
38
|
+
|
|
39
|
+
- name: Calculate new version
|
|
40
|
+
id: new
|
|
41
|
+
run: |
|
|
42
|
+
CURRENT="${{ steps.current.outputs.version }}"
|
|
43
|
+
BUMP="${{ inputs.bump || 'patch' }}"
|
|
44
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
|
|
45
|
+
|
|
46
|
+
case "$BUMP" in
|
|
47
|
+
patch) NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" ;;
|
|
48
|
+
minor) NEW_VERSION="$MAJOR.$((MINOR + 1)).0" ;;
|
|
49
|
+
major) NEW_VERSION="$((MAJOR + 1)).0.0" ;;
|
|
50
|
+
esac
|
|
51
|
+
|
|
52
|
+
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
|
|
53
|
+
echo "Bumping $CURRENT → $NEW_VERSION ($BUMP)"
|
|
54
|
+
|
|
55
|
+
- name: Bump version in pyproject.toml
|
|
56
|
+
run: |
|
|
57
|
+
sed -i "s/^version = \"${{ steps.current.outputs.version }}\"/version = \"${{ steps.new.outputs.version }}\"/" pyproject.toml
|
|
58
|
+
|
|
59
|
+
- name: Update CHANGELOG
|
|
60
|
+
run: |
|
|
61
|
+
DATE=$(date +%Y-%m-%d)
|
|
62
|
+
sed -i "s/## \[Unreleased\]/## [Unreleased]\n\n---\n\n## [${{ steps.new.outputs.version }}] — $DATE/" CHANGELOG.md
|
|
63
|
+
echo "" >> CHANGELOG.md
|
|
64
|
+
echo "[${{ steps.new.outputs.version }}]: https://github.com/enzomar/ceramic-fwk/compare/v${{ steps.current.outputs.version }}...v${{ steps.new.outputs.version }}" >> CHANGELOG.md
|
|
65
|
+
|
|
66
|
+
- name: Commit and tag
|
|
67
|
+
run: |
|
|
68
|
+
git add pyproject.toml CHANGELOG.md
|
|
69
|
+
git commit -m "release: v${{ steps.new.outputs.version }}"
|
|
70
|
+
git tag -a "v${{ steps.new.outputs.version }}" -m "Release v${{ steps.new.outputs.version }}"
|
|
71
|
+
|
|
72
|
+
- name: Push
|
|
73
|
+
run: |
|
|
74
|
+
git push origin main
|
|
75
|
+
git push origin "v${{ steps.new.outputs.version }}"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: Security Checks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
# Run weekly on Monday at 06:00 UTC
|
|
10
|
+
- cron: "0 6 * * 1"
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
security-events: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
dependency-audit:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.12"
|
|
25
|
+
|
|
26
|
+
- name: Install pip-audit
|
|
27
|
+
run: pip install pip-audit
|
|
28
|
+
|
|
29
|
+
- name: Install project dependencies
|
|
30
|
+
run: pip install -e "."
|
|
31
|
+
|
|
32
|
+
- name: Audit dependencies for known vulnerabilities
|
|
33
|
+
run: pip-audit --strict --desc --skip-editable
|
|
34
|
+
|
|
35
|
+
secret-scan:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
|
|
42
|
+
- name: TruffleHog secret scan
|
|
43
|
+
uses: trufflesecurity/trufflehog@main
|
|
44
|
+
with:
|
|
45
|
+
extra_args: --only-verified
|
|
46
|
+
|
|
47
|
+
security-sensitive-files:
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
if: github.event_name == 'pull_request'
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
with:
|
|
53
|
+
fetch-depth: 0
|
|
54
|
+
|
|
55
|
+
- name: Check for security-sensitive file changes
|
|
56
|
+
run: |
|
|
57
|
+
SECURITY_FILES=(
|
|
58
|
+
"ceramic/auth/oauth.py"
|
|
59
|
+
"ceramic/middleware/authentication.py"
|
|
60
|
+
"ceramic/auth/jwks_manager.py"
|
|
61
|
+
"ceramic/auth/token_storage.py"
|
|
62
|
+
"ceramic/security.py"
|
|
63
|
+
"ceramic/resilience.py"
|
|
64
|
+
"ceramic/identity.py"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
CHANGED_FILES=$(git diff --name-only origin/main...HEAD 2>/dev/null || echo "")
|
|
68
|
+
|
|
69
|
+
SECURITY_CHANGES=""
|
|
70
|
+
for file in "${SECURITY_FILES[@]}"; do
|
|
71
|
+
if echo "$CHANGED_FILES" | grep -q "^${file}$"; then
|
|
72
|
+
SECURITY_CHANGES="${SECURITY_CHANGES}\n- ${file}"
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
if [ -n "$SECURITY_CHANGES" ]; then
|
|
77
|
+
echo "⚠️ Security-sensitive files modified:"
|
|
78
|
+
echo -e "$SECURITY_CHANGES"
|
|
79
|
+
echo ""
|
|
80
|
+
echo "These files require careful review. Ensure:"
|
|
81
|
+
echo " - No tokens/secrets are logged"
|
|
82
|
+
echo " - TLS enforcement is preserved"
|
|
83
|
+
echo " - Circuit breaker protection is intact"
|
|
84
|
+
echo " - Tests cover rejection/failure cases"
|
|
85
|
+
fi
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Test Suite
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, "release/**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
unit-tests:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: pip install -e ".[dev]"
|
|
24
|
+
|
|
25
|
+
- name: Run unit tests
|
|
26
|
+
run: pytest tests/unit/ -v --tb=short
|
|
27
|
+
|
|
28
|
+
property-tests:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.12"
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: pip install -e ".[dev]"
|
|
39
|
+
|
|
40
|
+
- name: Run property-based tests
|
|
41
|
+
run: pytest tests/properties/ -v --hypothesis-seed=0
|
|
42
|
+
|
|
43
|
+
integration-tests:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: "3.12"
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies
|
|
53
|
+
run: pip install -e ".[dev]"
|
|
54
|
+
|
|
55
|
+
- name: Run integration tests
|
|
56
|
+
run: pytest tests/integration/ -v --tb=short
|
|
57
|
+
|
|
58
|
+
lint:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v4
|
|
62
|
+
|
|
63
|
+
- uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.12"
|
|
66
|
+
|
|
67
|
+
- name: Install dev dependencies
|
|
68
|
+
run: pip install -e ".[dev]" ruff mypy
|
|
69
|
+
|
|
70
|
+
- name: Ruff check
|
|
71
|
+
run: ruff check ceramic/ tests/
|
|
72
|
+
|
|
73
|
+
- name: Ruff format check
|
|
74
|
+
run: ruff format --check ceramic/ tests/
|
|
75
|
+
|
|
76
|
+
- name: Type check
|
|
77
|
+
run: mypy ceramic/ --ignore-missing-imports
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg-info/
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
*.egg
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv/
|
|
13
|
+
.venv-demo/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
.hypothesis/
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
|
|
29
|
+
# OS
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
|
|
33
|
+
# Ceramic
|
|
34
|
+
ceramic.yaml
|
|
35
|
+
!ceramic.yaml.example
|
|
36
|
+
!examples/zitadel/ceramic.yaml
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"specId": "02a335c8-4bf9-4916-b33d-e1245d3d1172", "workflowType": "requirements-first", "specType": "feature"}
|