Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(proposals): Decouple the trestle CLI from the SDK #68

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
174 changes: 174 additions & 0 deletions proposals/trestle-sdk-cli-decoupling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
title: Decouple the trestle CLI from the SDK
x-trestle-template-version: 0.0.1
authors:
- jpower432
description: Create a separately managed SDK
begin-design-discussions: 2024-08-22 #Insert
status: accepted #deferred, rejected, withdrawn or replaced - PR's are not accepted. Status is based on main. Rejected is unlikely to exist except where a clear record is required
---

**Checklist**


<!--> Add extra fields for management here <!-->

- [X] Template passes validation with `trestle`
- [X] Proposal cuts across multiple `oscal-compass` projects


## Summary/Abstract

This proposal outlines the rationale and steps for moving the `trestle` SDK from its current location within the CLI repository to a dedicated, standalone repository and separately managed Python package.

## Background

### Motivation and problem space

- **Community and Ecosystem**: There is no clear separation in `compliance-trestle` between what is designed as part of the `trestle` SDK and what directly supports CLI operations outside of the [`repository.py`](https://github.com/oscal-compass/compliance-trestle/blob/develop/trestle/core/repository.py). This can make it difficult to quickly identify and contribute to reusable logic which can limit adoption and growth.

- **Versioning Misalignment**: Updates to one component can introduce breaking changes for the other, making it difficult to maintain compatibility and avoid regressions.

- **Conflicting Dependencies**: When both the SDK and CLI share a common repository and Python package, they must use compatible versions of dependencies. This can lead to conflicts and limitations in the flexibility of both components. For instance, pinning dependencies for the CLI can provide stability but can limit flexibility and compatibility with different environments and applications for the SDK.

- **Scalability**: Managing the SDK in a separate repository would make it more straightforward to add new SDKs for other languages.

### Impact and desired outcome

**Improved Maintainability**: By reducing complexity and streamlining updates, the separation can make it easier to maintain and support both components.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have elaborated on this in the proposal and in earlier comments. Can you please give some feedback on what specifically you disagree with or what you see as missing or unclear?

Maintainability might more difficult. I think that OSCAL-SDK-CLI are tightly bound. Mixing and matching versions of OSCAL-SDK with CLIs might be challenging. It's not clear to me what the benefit of mixing and matching would be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree these are tightly bound. I believe part of the discussion was to explore the level of effort to change that. It agree it could result in initial challenges, but tightly coupled components have challenges as well. I don't think we should be mixing and matching versions of OSCAL and I agree that would be unexpected. The SDK would adopt new versions of OSCAL and the CLI would adopt the new version of the OSCAL through leveraged the SDK. I think this could also make the OSCAL upgrades simpler because it can be done in smaller increments.

**Increased Support for SDK Users**: Independent development and testing can lead to enhanced documentation and code quality targeting the SDK user.

## User/User Story (Optional)

None

### Prior discussion and links

Initial discussion occurred in the OSCAL Compass [community meeting](https://www.youtube.com/watch?v=uUGv3HXlTrI&t=19s ) on June 14, 2024 pertaining to the reusability of `Rule` logic to support this [issue](https://github.com/oscal-compass/compliance-trestle/issues/1475). An [issue](https://github.com/oscal-compass/community/issues/28) in the community repo was subsequently submitted.

## Goals

- `compliance-trestle` continues to contain the `trestle` CLI logic
- `compliance-trestle-python` is created as the Python SDK repository
- `compliance-trestle` and other OSCAL Compass projects migration to the new SDK for applicable logic

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please elaborate here on the branding issue and where you see a divergence with the current branding? Trestle is branded as an open source OSCAL SDK. From my perspective, that aligns with with the goals of this proposal.

From the first paragraph of the compliance-trestle README: ...and provides an opinionated approach to OSCAL adoption. It looks to me like the SDK will not be opinionated. Meaning that if one wishes to use the SDK to manipulate opinionated items, that won't be possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you are suggesting adding the ability to manipulate OSCAL extensions defined by trestle through the SDK would remedy this issue?

## Non-Goals

- Fundamentally changing the architecture or design of the SDK or CLI is out of scope.
- Expanding the SDK to other programming languages is out of scope (future consideration).

## Proposal

The solution proposed in this document is to move certain pieces of the codebase located in the [compliance-trestle](https://github.com/oscal-compass/compliance-trestle) repository to a new repository containing a Python-based SDK for interaction with OSCAL documents.

Below is high-level description of what would be moved:

**OSCAL Classes**: The classes that represent the OSCAL data model.

**Core Functionality**: Contains the fundamental APIs for interacting with OSCAL objects.

**Abstractions**: Abstractions for common operations like resolution or core OSCAL validation.

**Transformers**: A subset of the transformers with the following constraints:
- OSCAL to OSCAL Transformations only
- Transformation that do not require external data


</details>

## Design Details

Below is diagram with existing `trestle` logic that is proposed to be part of the SDK. Links to where this type of logic exists currently are included:

```mermaid
classDiagram
OSCALBaseModel <|-- Catalog
OSCALBaseModel <|-- Profile
OSCALBaseModel <|-- ComponentDefinitions
OSCALBaseModel <|-- SSP
OSCALBaseModel <|-- AssessmentPlan
OSCALBaseModel <|-- AssessmentResult
OSCALBaseModel <|-- POAM
class OSCALBaseModel{
+Config
+write()
+read()
}
class Catalog{
+CatalogAPI
}
class SSP{
+SSPInheritanceAPI
}
class Validator{
+isValid(OSCALBaseModel)
}
class Resolver{
+Fetcher
+import()
+merge()
+modify()
+prune()
}
```

### Relevant Links

- OSCAL Classes: https://github.com/oscal-compass/compliance-trestle/tree/develop/trestle/oscal
- Core Logic: https://github.com/oscal-compass/compliance-trestle/blob/develop/trestle/core/models/
- Abstractions:
- https://github.com/oscal-compass/compliance-trestle/tree/develop/trestle/core/resolver
- https://github.com/oscal-compass/compliance-trestle/blob/dfe892936e5960ad64f6f387dbe5918314049e89/trestle/core/validator.py

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a miscommunication here. The intention is to include more than the base classes and as @butler54 mentioned above, it provides a place where we can include functionality over time. This is covered in the proposal document. There is an initial diagram and some links to existing trestle packages there. Could you please provide more concrete feedback on the design details? If there is something you believe would be a beneficial addition to the SDK, please add a suggestion or comment there.

For sure, these classes can be moved to a separate repo. What I question is the value of doing so. It is surely the case that trestle versions are tightly coupled with OSCAL versions today. I'm having trouble imagining that the SDK will not be tightly coupled to OSCAL and that the CLI will not be tightly coupled to the SDK, version-wise. Thus, I'm having trouble understanding the value of separate repo, since a newer version of the SDK might very well be incompatible with and older version of the CLI, and vice-versa.

Copy link
Member Author

@jpower432 jpower432 Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see an SDK with well-defined interfaces as being useful to not only the CLI, but other projects. This provides a place to create reusable logic that is valuable outside of the context of the CLI. If the SDK has logic to support multiple projects interacting with OSCAL, I would think the CLI would have a different release cycle.

  • I agree the SDK would be tightly coupled to the OSCAL version
  • I agree the CLI should be leveraging a specific version of the SDK. For reusable functionality, the CLI can interact with the SDK through these defined interfaces (like the ProfileResolver).

I do not think the CLI would ever leverage the SDK and support different versions of OSCAL and agree that there would be compatibility issues there. If there is some wording in the proposal that indicates this is a use case, please let me know so I can change it.

This how I imagined the process:

  1. Create the release for SDK v1 (OSCAL 1.1.2)
  2. CLI at the current major version can migrate to SDK v1

Future Event - we are ready to move to OSCAL version 1.2.0

  1. SDK BREAKING CHANGE - SDK adopts OSCAL 1.2.0 and releases v2 for the CLI and other projects to leverage.
  2. CLI BREAKING CHANGE - Move to to SDK v2 to adopt OSCAL 1.2.0

Is this clarification helpful?

## Impacts / Key Questions

Some of my main questions around this proposal are the following:

- What will the contribution process look like for logic in `trestle`?
- Will the SDK be maintained by the `compliance-trestle` maintainer or by a new set of maintainers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please share what you are looking for in terms of community support? This was shared at the last community meeting and what I perceived is that with some updates to the implementation and more understanding of the level of effort, this was supported by the group.

If there is community support for this proposal please move forward. I've been known to be wrong. I will keep quiet now.

### Pros

- **Improved maintainability**: Easier to manage and update individual components.
- **Enhanced reusability**: SDK can be used in more applications and simplify contributions.
- **Reduced risk of breaking changes**: Fewer unintended consequences around codebase changes.

### Cons

- **Increased complexity**: Managing two separate repositories mean more project infrastructure to manage.
- **Initial effort**: Moving the SDK to a new repository requires upfront work.

## Risks and Mitigations

- **User Impact**: Breaking changes and movement will affect current SDK users and this will require community notifications and discussion as well as migration documentation.

### Security Considerations

- **Increased Attack Surface**: Managing more repositories and distinct codebases can potentially increase the attack surface.

## Future Milestones (Optional)

- Add a Go SDK to better support the C2P Go version and expand potential for integrations in the cloud native space.
Copy link

@yana1205 yana1205 Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for considering the use case of C2P.

This may have already been discussed, but I'd like to ask what you think about creating a Go binding?

The Go binding consists of OSCAL models (Go struct of Catalog/Profile/CDef/SSP/SAP/SAR/PoAM), and interfaces of OSCAL Base Model and validators. The interfaces are bound to the functions of the Python SDK.

Pros: Maintenance cost
Cons: Install Trestle-SDK and Python (or containerize them)

How to implement:

  • Wrap the functions as CLI or API so that Go binding can invoke it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing this up @yana1205. This is something I have considered, but it has not been discussed. I found it be more straight forward to call Go from Python instead of the other way around. On top of the cons you listed for the binding solution, complexity may add maintenance costs as well IMO.

As I understand it, we have an initial use case for Go from the C2P perspective (through the use case you mentioned below and through some of re-implementation in the C2P /go directory). I think we could explore the trade-offs in more details in a follow-on proposal.

To confirm, does the outcome of binding vs porting affect your thoughts on this proposal which was just SDK separation?


## Implementation Details (Optional)

### Testing Plan

This should be defined per sub-project repository.

### Update/Rollback Compatibility

The `compliance-trestle-python` SDK could be created first to test the rollout and once confirmed that it works as expected, the duplicate logic in `trestle` can removed and a new major version of `trestle` can be released. Version v3 of `compliance-trestle` will be available for users to rollback.

### Scalability

This change mainly impact project scalability and maintenance as noted in the above sections.

### Implementation Phases/History

The implementation can be completed in the following phases (high-level):

**Create an API Layer**: Define the packages we want to include in the SDK and use that to define an API layer in `compliance-trestle`
**Create the SDK**: Create an SDK repository and copy the packages from `compliance-trestle`. This will also give us an opportunity to setup a modernized build process covered in this [proposal](https://github.com/oscal-compass/community/pull/61).Setup documentation for SDK in the new repository and create the first release.
**Migration**: Migrate `compliance-trestle` from internal libraries to the SDK as a breaking change.