diff --git a/LICENSE b/LICENSE index c9cd9ecc..26b9f75c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ -Copyright 2025 Virtru Corporation -This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +Copyright 2026 Virtru Corporation +This work is licensed under the Creative Commons Attribution 4.0 International License. -Attribution-ShareAlike 4.0 International +Attribution 4.0 International ======================================================================= @@ -36,7 +36,7 @@ exhaustive, and do not form part of our licenses. material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors + wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the @@ -51,24 +51,22 @@ exhaustive, and do not form part of our licenses. rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees ======================================================================= -Creative Commons Attribution-ShareAlike 4.0 International Public -License +Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. Section 1 -- Definitions. @@ -87,11 +85,7 @@ Section 1 -- Definitions. and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights + c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or @@ -99,33 +93,29 @@ Section 1 -- Definitions. specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. - e. Effective Technological Measures means those measures that, in the + d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. - f. Exceptions and Limitations means fair use, fair dealing, and/or + e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, + f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. - i. Licensed Rights means the rights granted to You subject to the + g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. - j. Licensor means the individual(s) or entity(ies) granting rights + h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. - k. Share means to provide material to the public by any means or + i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material @@ -133,13 +123,13 @@ Section 1 -- Definitions. public may access the material from a place and at a time individually chosen by them. - l. Sui Generis Database Rights means rights other than copyright + j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. - m. You means the individual or entity exercising the Licensed Rights + k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. @@ -185,13 +175,7 @@ Section 2 -- Scope. Licensed Rights under the terms and conditions of this Public License. - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose + b. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the @@ -273,24 +257,9 @@ following conditions. information required by Section 3(a)(1)(A) to the extent reasonably practicable. - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. Section 4 -- Sui Generis Database Rights. @@ -305,9 +274,8 @@ apply to Your use of the Licensed Material: b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, + Rights (but not its individual contents) is Adapted Material; and - including for purposes of Section 3(b); and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. @@ -428,3 +396,4 @@ the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. + diff --git a/README.md b/README.md index a3f04374..f23ac996 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,165 @@ -# Website +# OpenTDF Documentation + +> The official documentation website for OpenTDF - an open source toolkit for zero trust, data-centric security. + +## About This Repository + +This repository contains the source code for the [OpenTDF documentation website](https://docs.opentdf.io), built using [Docusaurus](https://docusaurus.io/). The documentation provides comprehensive guides, tutorials, and reference materials for developers and organizations implementing data-centric security with OpenTDF. + +## What is OpenTDF? + +OpenTDF is an open source system for implementing data-centric security that enables: + +- **Zero Trust Data Protection**: Cryptographically bind access control policies to data objects +- **Attribute-Based Access Control (ABAC)**: Fine-grained access decisions based on attributes and context +- **Policy Travels with Data**: Security controls remain attached wherever data goes +- **Trust Data Format (TDF)**: Open standard for self-protecting data + +## Documentation Structure + +Our documentation follows a user-needs approach with four main categories: + +- **🚀 Tutorials**: Step-by-step learning experiences for hands-on practice +- **📖 How-To Guides**: Problem-solving recipes for specific tasks and integrations +- **💡 Explanations**: Conceptual guides covering the "why" behind OpenTDF's design +- **📚 Reference**: Technical specifications, API docs, and lookup information + +## Contributing + +We welcome contributions to improve our documentation! Please see our [Contributing Guide](CONTRIBUTING.md) for guidelines on: + +- Writing and editing documentation +- Style and formatting standards +- Review and approval process +- Technical setup for contributors + +For style guidelines, please refer to our [Style Guide](STYLE_GUIDE.md). + +## Quick Links + +- **Live Documentation**: [docs.opentdf.io](https://docs.opentdf.io) +- **OpenTDF Platform**: [github.com/opentdf/platform](https://github.com/opentdf/platform) +- **TDF Format Spec**: [github.com/opentdf/spec](https://github.com/opentdf/spec) +- **OpenTDF Organization**: [github.com/opentdf](https://github.com/opentdf) +- **Community Discussions**: [GitHub Discussions](https://github.com/opentdf/platform/discussions) + +--- + +## Local Development This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. -### Installation +### Prerequisites +Before you can run the documentation locally, you'll need Node.js and npm. We recommend using nvm (Node Version Manager) to manage Node.js versions. + +#### Option 1: Using nvm (Recommended) + +nvm allows you to install and switch between different Node.js versions easily. + +**Installation:** + +- **macOS/Linux**: Follow the installation instructions at [nvm GitHub repository](https://github.com/nvm-sh/nvm#installation-and-update) +- **Windows**: Install nvm-windows from [nvm-windows releases](https://github.com/coreybutler/nvm-windows#installation--upgrades) + +**Verify installation:** + +```bash +nvm --version # macOS/Linux +nvm version # Windows ``` -$ nvm use -$ npm ci -``` + +#### Option 2: Direct Node.js Installation + +If you prefer not to use nvm: + +1. **Visit [nodejs.org](https://nodejs.org/)** and download **Node.js version 22** (the version specified in our `.nvmrc` file) +2. **Follow the installation instructions** for your operating system +3. **Verify installation:** + + ```bash + node --version # Should show v22.x.x + npm --version # Should show npm version + ``` + +### Installation + +1. **Clone the repository:** + + ```bash + git clone https://github.com/opentdf/docs.git + cd docs + ``` + +2. **Use the correct Node.js version** (if using nvm): + + ```bash + nvm use # This reads the .nvmrc file and switches to Node.js v22 + ``` + + If you don't have Node.js v22 installed via nvm: + + ```bash + nvm install 22 + nvm use 22 + ``` + +3. **Install dependencies:** + + ```bash + npm ci # Installs exact versions from package-lock.json + ``` ### Local Development -``` -$ npm run start -``` + ```bash + npm run start + ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. ### Build + ```bash + npm run build + ``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Testing with Feature Branches + +The documentation site pulls content from multiple upstream repositories using Docusaurus remote content plugins. By default, content is fetched from the `main` branch of each repository. You can override this behavior using environment variables to test documentation changes from feature branches before they're merged. + +**Available Environment Variables:** + +- `PLATFORM_BRANCH` - Controls which branch to fetch from `opentdf/platform` (default: `main`) +- `SPEC_BRANCH` - Controls which branch to fetch from `opentdf/spec` (default: `main`) +- `OTDFCTL_BRANCH` - Controls which branch to fetch from `opentdf/otdfctl` (default: `main`) + +**Examples:** + +Test with all feature branches: +```bash +PLATFORM_BRANCH=my-platform-feature SPEC_BRANCH=my-spec-feature OTDFCTL_BRANCH=my-cli-feature npm run build ``` -$ npm run build + +Test with a single feature branch: +```bash +SPEC_BRANCH=feature-branch-name npm run build ``` -This command generates static content into the `build` directory and can be served using any static contents hosting service. +Test in development mode with feature branches: +```bash +PLATFORM_BRANCH=my-feature npm run start +``` + +**Use Cases:** + +- **Before merging PRs**: Test how documentation changes from upstream repos will look when integrated +- **Cross-repo changes**: When making coordinated changes across multiple repositories, test the full integration locally +- **Debugging**: Investigate issues with specific branches without affecting your local main branch + +**Note**: The branches must exist in the respective GitHub repositories and be accessible (public or you have access). ### Preview Deployment @@ -41,6 +177,7 @@ npx surge build opentdf-docs-preview-.surge.sh ``` **Examples:** + ```bash # Using ticket number npx surge build opentdf-docs-preview-dspx-2345.surge.sh @@ -52,3 +189,28 @@ npx surge build opentdf-docs-preview-troubleshooting-updates.surge.sh Your preview will be available at `https://opentdf-docs-preview-.surge.sh/` **Note:** The first time you deploy, Surge will prompt you to create a free account or login. + +--- + +## License + +This documentation is licensed under the [Creative Commons Attribution 4.0 International License (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). + +### License Change Notice + +**Effective Date: February 13, 2026** + +This project's documentation license has changed from: +- **Previous:** Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +- **New:** Creative Commons Attribution 4.0 International (CC BY 4.0) + +**What this means:** +- ✅ You can use, adapt, and share this documentation under any terms +- ✅ You only need to provide attribution to the original work +- ✅ No longer required to share derivative works under the same license (ShareAlike requirement removed) + +**Rationale:** To make the documentation more accessible and easier to integrate into various projects and contexts while maintaining proper attribution. + +All content committed after February 13, 2026 is licensed under CC BY 4.0. Content created before this date was released under CC BY-SA 4.0. + +See the [LICENSE](LICENSE) file for the full legal text. diff --git a/docusaurus.config.ts b/docusaurus.config.ts index cb8d5e40..363e2f0f 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -58,6 +58,12 @@ const config: Config = { logo: "https://docs.opentdf.io/img/opentdf-social.png", }), }, + { + tagName: "script", + attributes: { + src: "https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js", + }, + }, ], onBrokenLinks: "throw", @@ -198,8 +204,13 @@ const config: Config = { }, ], copyright: ` - Copyright © ${new Date().getFullYear()} OpenTDF - +
+ Copyright © ${new Date().getFullYear()} OpenTDF +
+
+ Documentation licensed under CC BY 4.0 • + Code licensed under BSD 3-Clause +
`, }, prism: { diff --git a/package.json b/package.json index d116f7b2..b73b0a8d 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "docs", "version": "0.0.0", "private": true, + "license": "CC-BY-4.0", "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", @@ -12,8 +13,9 @@ "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "gen-api-docs-all": "docusaurus gen-api-docs all --all-versions", + "gen-api-docs-all": "docusaurus gen-api-docs all --all-versions && npm run update-openapi-index", "gen-api-docs-clean": "docusaurus clean-api-docs all", + "update-openapi-index": "tsx scripts/update-openapi-index.ts", "check-vendored-yaml": "tsx src/openapi/check-vendored-yaml.ts", "update-vendored-yaml": "tsx src/openapi/update-vendored-yaml.ts" }, diff --git a/scripts/update-openapi-index.ts b/scripts/update-openapi-index.ts new file mode 100644 index 00000000..9c8dd33a --- /dev/null +++ b/scripts/update-openapi-index.ts @@ -0,0 +1,11 @@ +/** + * Post-processing script to update the OpenAPI index page with correct links + * after the OpenAPI docs have been generated. + */ + +import { updateOpenApiIndex, renameInfoFilesToIndex } from '../src/openapi/preprocessing'; + +console.log('🔄 Running post-generation OpenAPI processing...'); +renameInfoFilesToIndex(); +updateOpenApiIndex(); +console.log('✅ OpenAPI post-processing complete'); diff --git a/specs/policy/actions/actions.openapi.yaml b/specs/policy/actions/actions.openapi.yaml index 9e04d4e3..a3efaf59 100644 --- a/specs/policy/actions/actions.openapi.yaml +++ b/specs/policy/actions/actions.openapi.yaml @@ -497,23 +497,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -686,12 +669,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/attributes/attributes.openapi.yaml b/specs/policy/attributes/attributes.openapi.yaml index aa04ee67..8788f9ef 100644 --- a/specs/policy/attributes/attributes.openapi.yaml +++ b/specs/policy/attributes/attributes.openapi.yaml @@ -1014,23 +1014,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -1203,12 +1186,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/namespaces/namespaces.openapi.yaml b/specs/policy/namespaces/namespaces.openapi.yaml index a32f5db1..51632ed0 100644 --- a/specs/policy/namespaces/namespaces.openapi.yaml +++ b/specs/policy/namespaces/namespaces.openapi.yaml @@ -325,77 +325,6 @@ paths: application/json: schema: $ref: '#/components/schemas/policy.namespaces.RemovePublicKeyFromNamespaceResponse' - /policy.namespaces.NamespaceService/AssignCertificateToNamespace: - post: - tags: - - policy.namespaces.NamespaceService - summary: AssignCertificateToNamespace - description: Namespace <> Certificate RPCs - operationId: policy.namespaces.NamespaceService.AssignCertificateToNamespace - parameters: - - name: Connect-Protocol-Version - in: header - required: true - schema: - $ref: '#/components/schemas/connect-protocol-version' - - name: Connect-Timeout-Ms - in: header - schema: - $ref: '#/components/schemas/connect-timeout-header' - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/policy.namespaces.AssignCertificateToNamespaceRequest' - required: true - responses: - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - description: Success - content: - application/json: - schema: - $ref: '#/components/schemas/policy.namespaces.AssignCertificateToNamespaceResponse' - /policy.namespaces.NamespaceService/RemoveCertificateFromNamespace: - post: - tags: - - policy.namespaces.NamespaceService - summary: RemoveCertificateFromNamespace - operationId: policy.namespaces.NamespaceService.RemoveCertificateFromNamespace - parameters: - - name: Connect-Protocol-Version - in: header - required: true - schema: - $ref: '#/components/schemas/connect-protocol-version' - - name: Connect-Timeout-Ms - in: header - schema: - $ref: '#/components/schemas/connect-timeout-header' - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/policy.namespaces.RemoveCertificateFromNamespaceRequest' - required: true - responses: - default: - description: Error - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - description: Success - content: - application/json: - schema: - $ref: '#/components/schemas/policy.namespaces.RemoveCertificateFromNamespaceResponse' components: schemas: common.ActiveStateEnum: @@ -446,20 +375,6 @@ components: Describes whether this kas is managed by the organization or if they imported the kas information from an external party. These two modes are necessary in order to encrypt a tdf dek with an external parties kas public key. - common.IdFqnIdentifier: - type: object - properties: - id: - type: string - title: id - format: uuid - fqn: - type: string - title: fqn - minLength: 1 - format: uri - title: IdFqnIdentifier - additionalProperties: false common.Metadata: type: object properties: @@ -620,23 +535,6 @@ components: the Joda Time's [`ISODateTimeFormat.dateTime()`]( http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() ) to obtain a formatter capable of generating timestamps in this format. - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.KasPublicKey: type: object properties: @@ -758,12 +656,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.PageRequest: @@ -867,39 +759,6 @@ components: title: pem title: SimpleKasPublicKey additionalProperties: false - policy.namespaces.AssignCertificateToNamespaceRequest: - type: object - properties: - namespace: - title: namespace - description: Required - namespace identifier (id or fqn) - $ref: '#/components/schemas/common.IdFqnIdentifier' - pem: - type: string - title: pem - description: Required - PEM format certificate - metadata: - title: metadata - description: Optional - $ref: '#/components/schemas/common.MetadataMutable' - title: AssignCertificateToNamespaceRequest - required: - - namespace - - pem - additionalProperties: false - policy.namespaces.AssignCertificateToNamespaceResponse: - type: object - properties: - namespaceCertificate: - title: namespace_certificate - description: The mapping of the namespace to the certificate. - $ref: '#/components/schemas/policy.namespaces.NamespaceCertificate' - certificate: - title: certificate - description: Return the full certificate object for convenience - $ref: '#/components/schemas/policy.Certificate' - title: AssignCertificateToNamespaceResponse - additionalProperties: false policy.namespaces.AssignKeyAccessServerToNamespaceRequest: type: object properties: @@ -1057,24 +916,6 @@ components: $ref: '#/components/schemas/policy.PageResponse' title: ListNamespacesResponse additionalProperties: false - policy.namespaces.NamespaceCertificate: - type: object - properties: - namespace: - title: namespace - description: Required - namespace identifier (id or fqn) - $ref: '#/components/schemas/common.IdFqnIdentifier' - certificateId: - type: string - title: certificate_id - format: uuid - description: Required (The id from the Certificate object) - title: NamespaceCertificate - required: - - namespace - - certificateId - additionalProperties: false - description: Maps a namespace to a certificate (similar to NamespaceKey pattern) policy.namespaces.NamespaceKey: type: object properties: @@ -1109,26 +950,6 @@ components: title: NamespaceKeyAccessServer additionalProperties: false description: Deprecated - policy.namespaces.RemoveCertificateFromNamespaceRequest: - type: object - properties: - namespaceCertificate: - title: namespace_certificate - description: The namespace and certificate to unassign. - $ref: '#/components/schemas/policy.namespaces.NamespaceCertificate' - title: RemoveCertificateFromNamespaceRequest - required: - - namespaceCertificate - additionalProperties: false - policy.namespaces.RemoveCertificateFromNamespaceResponse: - type: object - properties: - namespaceCertificate: - title: namespace_certificate - description: The unassigned namespace and certificate. - $ref: '#/components/schemas/policy.namespaces.NamespaceCertificate' - title: RemoveCertificateFromNamespaceResponse - additionalProperties: false policy.namespaces.RemoveKeyAccessServerFromNamespaceRequest: type: object properties: diff --git a/specs/policy/objects.openapi.yaml b/specs/policy/objects.openapi.yaml index 73ff1404..c1f082cc 100644 --- a/specs/policy/objects.openapi.yaml +++ b/specs/policy/objects.openapi.yaml @@ -355,23 +355,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -605,12 +588,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/obligations/obligations.openapi.yaml b/specs/policy/obligations/obligations.openapi.yaml index 904b7706..a0bc8c8c 100644 --- a/specs/policy/obligations/obligations.openapi.yaml +++ b/specs/policy/obligations/obligations.openapi.yaml @@ -846,23 +846,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -1035,12 +1018,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/registeredresources/registered_resources.openapi.yaml b/specs/policy/registeredresources/registered_resources.openapi.yaml index 0a481f4c..676ab81a 100644 --- a/specs/policy/registeredresources/registered_resources.openapi.yaml +++ b/specs/policy/registeredresources/registered_resources.openapi.yaml @@ -707,23 +707,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -896,12 +879,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/resourcemapping/resource_mapping.openapi.yaml b/specs/policy/resourcemapping/resource_mapping.openapi.yaml index 69cdbc4a..86b0d952 100644 --- a/specs/policy/resourcemapping/resource_mapping.openapi.yaml +++ b/specs/policy/resourcemapping/resource_mapping.openapi.yaml @@ -707,23 +707,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -896,12 +879,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/subjectmapping/subject_mapping.openapi.yaml b/specs/policy/subjectmapping/subject_mapping.openapi.yaml index 4d0e7f1b..f8dcc5ba 100644 --- a/specs/policy/subjectmapping/subject_mapping.openapi.yaml +++ b/specs/policy/subjectmapping/subject_mapping.openapi.yaml @@ -743,23 +743,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -932,12 +915,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/specs/policy/unsafe/unsafe.openapi.yaml b/specs/policy/unsafe/unsafe.openapi.yaml index c604fa65..bf346f58 100644 --- a/specs/policy/unsafe/unsafe.openapi.yaml +++ b/specs/policy/unsafe/unsafe.openapi.yaml @@ -721,23 +721,6 @@ components: required: - rule additionalProperties: false - policy.Certificate: - type: object - properties: - id: - type: string - title: id - description: generated uuid in database - pem: - type: string - title: pem - description: PEM format certificate - metadata: - title: metadata - description: Optional metadata. - $ref: '#/components/schemas/common.Metadata' - title: Certificate - additionalProperties: false policy.Condition: type: object properties: @@ -946,12 +929,6 @@ components: $ref: '#/components/schemas/policy.SimpleKasKey' title: kas_keys description: Keys for the namespace - rootCerts: - type: array - items: - $ref: '#/components/schemas/policy.Certificate' - title: root_certs - description: Root certificates for chain of trust title: Namespace additionalProperties: false policy.Obligation: diff --git a/src/css/custom.css b/src/css/custom.css index 4054e8a9..740935f3 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -4,6 +4,9 @@ * work well for content-centric websites. */ +/* Import marketing styles for homepage */ +@import './marketing.css'; + /* You can override the default Infima variables here. */ /* :root { --ifm-color-primary: #2e8555; diff --git a/src/css/marketing.css b/src/css/marketing.css new file mode 100644 index 00000000..78ba9ddc --- /dev/null +++ b/src/css/marketing.css @@ -0,0 +1,265 @@ +/* Marketing Homepage Styles */ + +.marketing-hero { + padding: 4rem 0; + position: relative; + overflow: hidden; +} + +.marketing-hero--primary { + background: linear-gradient(135deg, var(--ifm-color-primary) 0%, var(--ifm-color-primary-dark) 100%); + color: white; +} + +.marketing-hero--secondary { + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + color: var(--ifm-color-gray-900); +} + +.marketing-hero--dark { + background: linear-gradient(135deg, var(--ifm-color-gray-900) 0%, var(--ifm-color-gray-800) 100%); + color: white; +} + +.marketing-hero--accent { + background: linear-gradient(135deg, var(--ifm-color-success) 0%, var(--ifm-color-success-dark) 100%); + color: white; +} + +.hero-content { + display: flex; + align-items: center; + gap: 3rem; + min-height: 400px; +} + +.hero-content--reverse { + flex-direction: row-reverse; +} + +.hero-text { + flex: 1; +} + +.hero-visual { + flex: 0 0 auto; + display: flex; + align-items: center; + justify-content: center; +} + +.hero-icon { + font-size: 8rem; + opacity: 0.9; + filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1)); +} + +.hero-title { + font-size: 3.5rem; + font-weight: 800; + margin-bottom: 1.5rem; + line-height: 1.2; +} + +.hero-subtitle { + font-size: 1.3rem; + margin-bottom: 2rem; + opacity: 0.9; + line-height: 1.6; +} + +.hero-actions { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.hero-button { + padding: 0.75rem 2rem; + font-size: 1.1rem; + font-weight: 600; + border-radius: 8px; + text-decoration: none; + transition: all 0.2s ease; + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.hero-button--primary { + background: rgba(255,255,255,0.2); + color: white; + border: 2px solid rgba(255,255,255,0.3); +} + +.hero-button--primary:hover { + background: rgba(255,255,255,0.3); + color: white; + text-decoration: none; + transform: translateY(-2px); +} + +.hero-button--secondary { + background: transparent; + color: inherit; + border: 2px solid currentColor; +} + +.hero-button--secondary:hover { + background: rgba(255,255,255,0.6); + color: gray; + text-decoration: none; + transform: translateY(-2px); +} + +.hero-button--solid { + background: var(--ifm-color-primary); + color: white; + border: 2px solid var(--ifm-color-primary); +} + +.hero-button--solid:hover { + background: var(--ifm-color-primary-dark); + border-color: var(--ifm-color-primary-dark); + color: white; + text-decoration: none; + transform: translateY(-2px); +} + +/* Responsive Design */ +@media (max-width: 768px) { + .hero-content { + flex-direction: column !important; + text-align: center; + gap: 2rem; + min-height: 300px; + } + + .hero-content--reverse { + flex-direction: column !important; + } + + .hero-title { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1.1rem; + } + + .hero-icon { + font-size: 5rem; + } + + .hero-actions { + justify-content: center; + } +} + +/* Navigation Enhancement */ +.navbar { + backdrop-filter: blur(10px); + background: rgba(255, 255, 255, 0.95); + border-bottom: 1px solid rgba(0,0,0,0.1); +} + +/* Animation Classes */ +.fade-in { + animation: fadeIn 0.8s ease-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.slide-in-right { + animation: slideInRight 1s ease-out; +} + +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.slide-in-left { + animation: slideInLeft 1s ease-out; +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +/* Hero list */ +.hero-list { + margin: 0.5rem 0 1rem 1.5rem; + color: inherit; + opacity: 0.9; +} + +.hero-list li { + margin-bottom: 0.4rem; +} + +/* Final CTA section */ +.marketing-cta { + padding: 4rem 0; + text-align: center; + background: #f8f9fa; +} + +.marketing-cta__title { + font-size: 2.5rem; + margin-bottom: 1rem; + color: var(--ifm-color-primary); +} + +.marketing-cta__subtitle { + font-size: 1.2rem; + margin-bottom: 2rem; + opacity: 0.8; +} + +.marketing-cta__actions { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; +} + +/* Visual enhancements */ +.hero-icon-container { + position: relative; +} + +.hero-icon-container::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 120%; + height: 120%; + background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); + border-radius: 50%; + z-index: -1; +} \ No newline at end of file diff --git a/src/openapi/preprocessing.ts b/src/openapi/preprocessing.ts index 1e410980..d886855f 100644 --- a/src/openapi/preprocessing.ts +++ b/src/openapi/preprocessing.ts @@ -4,6 +4,7 @@ When making changes to this file, consider: https://virtru.atlassian.net/browse/ import * as fs from 'fs'; import * as path from 'path'; import * as yaml from 'js-yaml'; +import matter from 'gray-matter'; import type * as OpenApiPlugin from "docusaurus-plugin-openapi-docs"; // Utility to find the repo root (directory containing package.json) @@ -30,6 +31,35 @@ const OUTPUT_PREFIX = path.join(repoRoot, 'docs', 'OpenAPI-clients'); // The index page for OpenAPI documentation, to support bookmarking & sharing the URL const OPENAPI_INDEX_PAGE = `${OUTPUT_PREFIX}/index.md`; +// Service descriptions and categorization for OpenAPI index generation +const SERVICE_DESCRIPTIONS: Record = { + 'Well-Known Configuration': 'Platform configuration and service discovery', + 'kas': 'Key Access Service for TDF encryption/decryption', + 'V1 Authorization': 'Authorization decisions (v1)', + 'V2 Authorization': 'Authorization decisions (v2)', + 'V1 Entity Resolution': 'Entity resolution from JWT tokens (v1)', + 'V2 Entity Resolution': 'Entity resolution from tokens (v2)', + 'Policy Objects': 'Core policy objects and management', + 'Policy Attributes': 'Attribute definitions and values', + 'Policy Namespaces': 'Namespace management', + 'Policy Actions': 'Action definitions', + 'Policy Subject Mapping': 'Map subjects to attributes', + 'Policy Resource Mapping': 'Map resources to attributes', + 'Policy Obligations': 'Usage obligations and triggers', + 'Policy Registered Resources': 'Resource registration', + 'Policy KAS Registry': 'KAS registration and management', + 'Key Management': 'Cryptographic key management', + 'Policy Unsafe Service': 'Administrative operations', +}; + +const CATEGORY_MAPPING: Record = { + 'Core Services': ['Well-Known Configuration', 'kas'], + 'Authorization & Entity Resolution': ['V1 Authorization', 'V2 Authorization', 'V1 Entity Resolution', 'V2 Entity Resolution'], + 'Policy Management': ['Policy Objects', 'Policy Attributes', 'Policy Namespaces', 'Policy Actions', + 'Policy Subject Mapping', 'Policy Resource Mapping', 'Policy Obligations', + 'Policy Registered Resources', 'Policy KAS Registry', 'Key Management', 'Policy Unsafe Service'], +}; + // Read BUILD_OPENAPI_SAMPLES once const BUILD_OPENAPI_SAMPLES = process.env.BUILD_OPENAPI_SAMPLES === '1'; @@ -414,27 +444,130 @@ async function preprocessOpenApiSpecs() { delete spec.specPathModified; } - // Create the index page for OpenAPI documentation + console.log('✨ OpenAPI preprocessing complete'); +}; + + +/** + * Renames all .info.mdx files to index.mdx so they become category index pages + * instead of appearing as separate items in the sidebar. + */ +function renameInfoFilesToIndex() { + console.log('🔄 Renaming .info.mdx files to index.mdx...'); + + function processDirectory(dir: string) { + if (!fs.existsSync(dir)) return; + + const items = fs.readdirSync(dir, { withFileTypes: true }); + + for (const item of items) { + const fullPath = path.join(dir, item.name); + + if (item.isDirectory()) { + processDirectory(fullPath); + } else if (item.name.endsWith('.info.mdx')) { + const newPath = path.join(dir, 'index.mdx'); + fs.renameSync(fullPath, newPath); + console.log(` Renamed: ${fullPath} → ${newPath}`); + } + } + } + + processDirectory(OUTPUT_PREFIX); + console.log('✅ Renamed all .info.mdx files to index.mdx'); +} + +/** + * Updates the OpenAPI index page with links to generated docs. + * This should be called AFTER the OpenAPI docs have been generated. + */ +function updateOpenApiIndex() { + console.log('📝 Updating OpenAPI index page with generated doc links...'); + + // Helper function to find and read the document ID from a generated index.mdx file + function getDocIdFromInfoFile(outputDir: string): string | null { + try { + if (!fs.existsSync(outputDir)) { + return null; + } + + const indexPath = path.join(outputDir, 'index.mdx'); + + if (fs.existsSync(indexPath)) { + const fileContent = fs.readFileSync(indexPath, 'utf8'); + const parsed = matter(fileContent); + + if (parsed.data.id) { + const relativePath = path.relative(OUTPUT_PREFIX, outputDir); + return `OpenAPI-clients/${relativePath}`; + } + } + } catch (error) { + // Silently skip if file doesn't exist yet + } + return null; + } + + // Build service links dynamically from openApiSpecsArray + // Track which specs are categorized to find uncategorized ones + const categorizedSpecs = new Set(); + let serviceLinksMarkdown = ''; + + Object.entries(CATEGORY_MAPPING).forEach(([category, specIds]) => { + serviceLinksMarkdown += `\n## ${category}\n\n`; + specIds.forEach(specId => { + categorizedSpecs.add(specId); + const spec = openApiSpecsArray.find(s => s.id === specId); + if (spec) { + const docId = getDocIdFromInfoFile(spec.outputDir); + if (docId) { + const description = SERVICE_DESCRIPTIONS[specId] || 'API documentation'; + serviceLinksMarkdown += `- **[${spec.id}](/${docId})** - ${description}\n`; + } + } + }); + }); + + // Add uncategorized APIs to a catch-all category + const uncategorizedSpecs = openApiSpecsArray.filter(spec => !categorizedSpecs.has(spec.id)); + if (uncategorizedSpecs.length > 0) { + console.warn(`⚠️ Found ${uncategorizedSpecs.length} uncategorized API(s): ${uncategorizedSpecs.map(s => s.id).join(', ')}`); + serviceLinksMarkdown += `\n## Other APIs\n\n`; + uncategorizedSpecs.forEach(spec => { + const docId = getDocIdFromInfoFile(spec.outputDir); + if (docId) { + const description = SERVICE_DESCRIPTIONS[spec.id] || 'API documentation'; + serviceLinksMarkdown += `- **[${spec.id}](/${docId})** - ${description}\n`; + } + }); + } + const indexContent = `--- title: OpenAPI Clients sidebar_position: 7 --- # OpenAPI Clients -OpenAPI client examples are available for platform endpoints. +Interactive API documentation for OpenTDF Platform services. Each endpoint includes request/response examples, parameter descriptions, and the ability to try requests directly in your browser. -Expand each section in the navigation panel to access the OpenAPI documentation for each service. -` +${serviceLinksMarkdown} - // Ensure the file 'OPENAPI_INDEX_PAGE' exists - fs.mkdirSync(path.dirname(OPENAPI_INDEX_PAGE), { recursive: true }); +## Getting Started - fs.writeFileSync(OPENAPI_INDEX_PAGE, indexContent, 'utf8'); - console.log(`✅ Created OpenAPI index page at ${OPENAPI_INDEX_PAGE}`); +1. Select a service from the list above or navigation sidebar +2. Browse available endpoints and operations +3. Review request parameters and response schemas +4. Test endpoints using the "Try it" feature - console.log('✨ OpenAPI preprocessing complete'); -}; +## Authentication + +Most endpoints require authentication. Configure your access token in the API documentation interface before testing endpoints. +`; + fs.mkdirSync(path.dirname(OPENAPI_INDEX_PAGE), { recursive: true }); + fs.writeFileSync(OPENAPI_INDEX_PAGE, indexContent, 'utf8'); + console.log(`✅ Updated OpenAPI index page at ${OPENAPI_INDEX_PAGE}`); +} // Export the function and data without automatically executing it -export { openApiSpecs, openApiSpecsArray, preprocessOpenApiSpecs }; \ No newline at end of file +export { openApiSpecs, openApiSpecsArray, preprocessOpenApiSpecs, updateOpenApiIndex, renameInfoFilesToIndex }; \ No newline at end of file diff --git a/src/pages/index.module.css b/src/pages/index.module.css index d1a89ba6..41ed7ea5 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -3,3 +3,274 @@ * and scoped locally. */ +/* Marketing Homepage Styles */ + +/* Hero Sections */ +.marketing-hero { + padding: 6rem 0; + position: relative; + overflow: hidden; +} + +.marketing-hero--primary { + background: linear-gradient(135deg, var(--ifm-color-primary) 0%, var(--ifm-color-primary-darker) 100%); + color: white; +} + +.marketing-hero--secondary { + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + color: var(--ifm-color-emphasis-800); +} + +.marketing-hero--dark { + background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); + color: white; +} + +.marketing-hero--accent { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +/* Hero Content Layout */ +.hero-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4rem; + align-items: center; + min-height: 400px; +} + +.hero-content--reverse { + grid-template-areas: "visual text"; +} + +.hero-content--reverse .hero-text { + grid-area: text; +} + +.hero-content--reverse .hero-visual { + grid-area: visual; +} + +.hero-text { + z-index: 2; +} + +.hero-title { + font-size: 3rem; + font-weight: 800; + line-height: 1.2; + margin-bottom: 1.5rem; + background: linear-gradient(135deg, currentColor 0%, rgba(255,255,255,0.8) 100%); + background-clip: text; + -webkit-background-clip: text; +} + +.hero-subtitle { + font-size: 1.25rem; + line-height: 1.6; + margin-bottom: 2rem; + opacity: 0.9; +} + +/* Hero Actions */ +.hero-actions { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.hero-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 1rem 2rem; + border-radius: 0.5rem; + font-weight: 600; + text-decoration: none; + transition: all 0.3s ease; + border: 2px solid; + font-size: 1rem; +} + +.hero-button--primary { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.3); + color: white; + backdrop-filter: blur(10px); +} + +.hero-button--primary:hover { + background: rgba(255, 255, 255, 0.2); + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); +} + +.hero-button--secondary { + background: transparent; + border-color: currentColor; + color: inherit; +} + +.hero-button--secondary:hover { + background: currentColor; + color: white; + text-decoration: none; + transform: translateY(-2px); +} + +.hero-button--solid { + background: var(--ifm-color-primary); + border-color: var(--ifm-color-primary); + color: white; +} + +.hero-button--solid:hover { + background: var(--ifm-color-primary-dark); + border-color: var(--ifm-color-primary-dark); + color: white; + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); +} + +/* Hero Visual */ +.hero-visual { + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.hero-icon-container { + width: 200px; + height: 200px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + backdrop-filter: blur(10px); + border: 2px solid rgba(255, 255, 255, 0.2); +} + +.hero-icon { + font-size: 4rem; + color: currentColor; +} + +/* Animations */ +.fade-in { + animation: fadeIn 1s ease-out; +} + +.slide-in-right { + animation: slideInRight 1s ease-out; +} + +.slide-in-left { + animation: slideInLeft 1s ease-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-50px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + .hero-content { + grid-template-columns: 1fr; + gap: 2rem; + text-align: center; + } + + .hero-content--reverse { + grid-template-areas: + "text" + "visual"; + } + + .hero-title { + font-size: 2.5rem; + } + + .hero-subtitle { + font-size: 1.1rem; + } + + .hero-actions { + justify-content: center; + } + + .hero-button { + padding: 0.875rem 1.5rem; + font-size: 0.9rem; + } + + .marketing-hero { + padding: 4rem 0; + } + + .hero-icon-container { + width: 150px; + height: 150px; + } + + .hero-icon { + font-size: 3rem; + } +} + +@media (max-width: 480px) { + .hero-title { + font-size: 2rem; + } + + .hero-subtitle { + font-size: 1rem; + } + + .hero-actions { + flex-direction: column; + align-items: center; + } + + .hero-button { + width: 100%; + max-width: 280px; + justify-content: center; + } +} + diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 5304464d..63a3260a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,103 +1,239 @@ import React from "react"; import Layout from "@theme/Layout"; import Head from "@docusaurus/Head"; -import { Columns, Hero, Features, Feedback } from "../components/Homepage"; export default function Home() { return ( -
+
- + - - -

- OpenTDF is an open source system for implementing data centric security. - It provides the basic services required to enable the definition, application, - and enforcement of attribute based policies using the Trust Data Format (TDF). - TDF is an open standard that enables you to cryptographically bind - attribute based access control (ABAC) policy to a data object so that - the policy travels with the data wherever it goes. -

-

- OpenTDF builds upon a decade of experience at Virtru - protecting data objects at scale using the Trusted Data Format - for organizations of all sizes and across all industries. -

-
- - -

- Today's cybersecurity landscape is increasingly adopting and requiring Zero Trust models and frameworks. - Zero Trust operates on the principle of "never trust, always verify," - ensuring that every access request is authenticated, authorized, and encrypted, - regardless of its origin. OpenTDF implements this model by providing an open-source framework, specification, and set of services - that prioritizes the protection and integrity of data at every stage. -

-

- By integrating OpenTDF’s data security features with a Zero Trust architecture, - organizations can enforce strict access controls, ensure data is continuously monitored, - and maintain comprehensive visibility into data interactions. This synergy not only - minimizes the risk of data breaches but also fosters a secure environment where data - can be shared and utilized with confidence. Together, Zero Trust and OpenTDF empower businesses - to uphold the highest standards of data security in an interconnected world. -

-
- -

- In 2023, the OpenTDF team undertook a significant re-architecture - of the OpenTDF platform to enhance its extensibility and interoperability, - responding to the evolving needs of our diverse user base and the dynamic cybersecurity landscape. - See our {" "}Github Organization Page to navigate the new repositories. -

-

- This comprehensive overhaul involved simplifying core service components, - adopting standardized policy schemas, and improving platform APIs and SDKs both in - developer experience and in capability. By focusing on extensibility, we have enabled - developers to customize and extend OpenTDF’s functionalities to suit specific use cases, - fostering innovation and adaptability. As we continue to advance, our focus remains on empowering the community with a secure, adaptable, - and interoperable platform that meets the highest standards of data protection and fosters collaborative innovation. -

-

- Through the sponsorship of Virtru and its partners, the OpenTDF project has been - meeting the needs of customers across industries and use cases. Check out{" "} - - Virtru Data Security Platform - {" "} - for more. + + + {/* Hero 1: Main Value Proposition */} +

+
+
+
+

Protect the Data, Build the Future

+

+ Open-source data-centric security for developers. OpenTDF delivers the Trusted Data Format (TDF) specification, + foundational services for key management and access control, and SDKs — the building blocks to cryptographically + bind protection directly to your data, wherever it goes. +

+

+ Explore the standard. Prototype custom applications. Build architectures where security travels with the data, not the network. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Hero 2: Problem/Solution */} +
+
+
+
+

Traditional Security Fails When Data Leaves the Perimeter

+

+ Firewalls, VPNs, and network policies protect the boundary — not the data. + The moment a file is shared, downloaded, or moved to a new environment, + those controls vanish. Access decisions remain at the perimeter, while the + data moves on without them. +

+

+ OpenTDF inverts this model. Policies travel with the data itself, so you can: +

+
    +
  • Revoke access after sharing — even after data has left your environment
  • +
  • Enforce controls in zero-trust environments — no VPN, no network dependency
  • +
  • Maintain a complete audit trail — know who accessed what, when, and where
  • +
+

+ This is data-centric security: protection that's embedded, not bolted on. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Hero 3: Developer-First */} +
+
+
+
+

Built for Developers

+

+ Native SDKs for Go, Java, and JavaScript. RESTful APIs. Comprehensive documentation. + Get started in minutes, not months. OpenTDF provides the tools developers need to build + secure applications without sacrificing speed or simplicity. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Hero 4: Enterprise Trust */} +
+
+
+
+

Trusted by Organizations Worldwide

+

+ Built on a decade of Virtru's experience protecting data at scale. OpenTDF powers + secure data sharing for organizations across industries—from healthcare and finance + to government and defense. Battle-tested, enterprise-ready, open source. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Hero 5: Standards & Compliance */} +
+
+
+
+

Standards-Based Security

+

+ Built on the proven NIST ABAC model for interoperability and compliance. + OpenTDF follows established standards for attribute-based access control, + ensuring your data protection strategy is future-proof and audit-ready. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Hero 6: Community */} +
+
+
+
+

Join the Movement

+

+ Open source, open community. Shape the future of data-centric security with developers, + security professionals, and organizations from around the world. Contribute code, + share ideas, and help build the next generation of data protection. +

+ +
+
+
+ +
+
+
+
+
+ + {/* Final CTA Section */} +
+
+

+ Ready to Protect Your Data? +

+

+ Choose your path and start building with OpenTDF today.

- - - - {/* */} - - - - -

- Virtru, the sponsor of the OpenTDF developer community, would love to hear from you! -

-

- We're developers, too, and as we mature the project, we're curious what you're building, and what kind of problems you may be encountering or are trying to solve. -

-

- You can provide anonymous feedback (name, email, and company are not required fields on this form), or share your contact information for access to curated resources, updates, and if you request a response. -

-
+ +
+
+
);