Skip to content

About

Crossplane v2 provider for Logto, powered by Upjet with embedded Terraform Framework

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

402 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

provider-upjet-logto

CCSN Crossplane provider generated with Upjet v2 from a checked-in source snapshot of the terraform-provider-logto fork (based on Lenstra v0.0.15, MIT). The controller embeds the Terraform Plugin Framework provider through protocol v6; Terraform/OpenTofu is required only to regenerate the schema.

Resources

Each resource has a namespaced API and a legacy cluster-scoped API, version v1alpha1. Prefer namespaced resources on Crossplane v2.

Terraform resource Namespaced API group Kind
logto_application application.logto.m.crossplane.io Application
logto_application_secret application.logto.m.crossplane.io Secret
logto_application_user_consent_scopes application.logto.m.crossplane.io UserConsentScopes
logto_api_resource api.logto.m.crossplane.io Resource
logto_api_resource_scope api.logto.m.crossplane.io Scope
logto_connector connector.logto.m.crossplane.io Connector
logto_sign_in_experience configuration.logto.m.crossplane.io SignInExperience
logto_account_center configuration.logto.m.crossplane.io AccountCenter
logto_id_token_config configuration.logto.m.crossplane.io IDTokenConfiguration
logto_oidc_session_config configuration.logto.m.crossplane.io OIDCSessionConfiguration
logto_role role.logto.m.crossplane.io Role
logto_user user.logto.m.crossplane.io User

References connect secrets to applications, scopes to APIs, roles to scopes, and users to roles. Configure credentials with a logto.m.crossplane.io/v1beta1 ProviderConfig in the managed resource's namespace, or a ClusterProviderConfig. The referenced Secret's credentials key contains JSON with hostname (hostname only, no scheme), resource (Management API audience), application_id, and application_secret. Use a machine-to-machine application authorized for Management API all; for the default OSS tenant the audience is commonly https://default.logto.app/api (verify it in your console).

Application exports clientId and existing named secrets as internal state connection details. Secret exports clientId, clientSecret, and attribute.value (reserved by Upjet for state reconstruction). Credential values are absent from CRD spec/status. writeConnectionSecretToRef writes a Secret in the resource's namespace. The Secret kind in this API group is a Logto managed resource, distinct from a core Kubernetes Secret.

Local development

The repository builds independently. go.mod points to the reviewed source snapshot in third_party/terraform-provider-logto; its manifest records the upstream base and SHA-256 of every included file. To update it from the adjacent fork, run make sync-provider, review the diff, then regenerate and verify. make snapshot detects accidental modifications to the embedded source.

nix develop path:.
make generate
make verify

make generate builds the fork, extracts its schema using a local development override (no registry installation/init), scrapes local resource docs, and runs Upjet, controller-gen and angryjet. Schema exports use a canonical registry address so Terraform and OpenTofu produce identical generated files. make verify checks the snapshot, runs offline race tests and vet in both modules, and builds a static controller under .work/bin/provider. Caches stay in ../.local; override GOMODCACHE, GOCACHE, or GOPATH if needed. When the default Go proxy is unavailable, set GOPROXY to your preferred mirror. Generated CRDs are in package/crds; runtime image definition is in cluster/images/provider-upjet-logto/Dockerfile. The runtime image uses a digest-pinned nonroot base. make image builds it without accessing credentials. Distribution still requires an approved package registry, signed release process, and a tested Crossplane package.

Existing SSO adoption

Start with examples/namespaced/application/import.yaml and managementPolicies: [Observe]; fill verified application IDs and named-secret IDs. New application and named-secret examples are in application.yaml; they intentionally omit Delete. Keep the existing consumer Secret distribution until the connection Secret has been checked. No production Flux kustomization includes these files.

Named secrets and legacy application secrets are separate Logto APIs. This provider does not rotate or import legacy secrets. Replacing a named-secret resource explicitly replaces the owned credential; expiry and rotation policies are not implemented yet. Application client_secrets is read-only and never creates or rotates secrets. Terraform sensitive fields are still present in Terraform state; use an encrypted and access-controlled backend.

Third-party application consent scopes

UserConsentScopes references an Application with applicationIdRef and authoritatively manages its userScopes, for example [profile, email]. Use one consent resource per application. Omit openid, which is implicit. The controller detects drift, revokes obsolete user scopes, and assigns missing scopes in place; an explicit userScopes: [] revokes all user profile scopes. A missing userScopes value never requests revocation. Explicit forProvider.userScopes values, including [], override initProvider.userScopes. Initialization grants remain retryable until they converge. Valid partial creations retain their external application ID even when a mutation fails, so restarts and deletion can recover without losing ownership. After convergence, changes to initialization values and external grants are observed without modifying grants. Use forProvider.userScopes for continuous management. The controller persists initialization completion in the logto.crossplane.io/user-consent-scopes-initialized annotation across restarts. A new resource becomes Ready after its initial grants converge and completion is persisted. Concurrent GitOps changes cause metadata writes to retry with a fresh resource snapshot. Grant mutations use the synchronous Framework connector, so initialization is confirmed by a fresh read after the write finishes. A parent supplied only in initProvider.applicationId is never promoted into forProvider, including when late initialization is enabled or initial grants must retry. Removing the initial parent configuration preserves this behavior. After initialization, that parent remains fixed until a missing resource is recreated. Recreating a missing resource uses the current initialization defaults and resolves their references again. Completed initial references cannot block ongoing observation or explicit permission changes. Adopting an existing application by external name also ignores its initial references before the initialization marker is persisted. Recreation preparation preserves completion until a fresh read confirms absence; a parent that reappears retains its previous initialization state. API resource and organization consent scopes are preserved. Import uses the application ID. Deletion revokes user profile scopes without deleting the app; omit Delete from managementPolicies to retain grants when removing the CR. Users still approve requested permissions on Logto's consent screen.

See examples/namespaced/application/consent-scopes.yaml. This CR requires a provider package built from this revision or newer. Publish that package and update the GitOps provider digest before reconciling manifests using the new kind; the previously released v0.1.0 package does not include this controller.

Validation and remaining scope

Offline tests cover all twelve resource lifecycles and Framework protocol v6 create/plan/update/read/delete, partial creation, pagination, bounded retries and cancellation, token reuse/refresh/concurrency, sensitive schemas, idempotent deletion, metadata preservation, credentials isolation, and status redaction. All 29 CRDs pass the Kubernetes API server structural/CEL validation functions. Real acceptance tests use the integration build tag and temporary loopback-only LOGTO_TEST_CREDENTIALS. make test-integration starts an isolated API Server and executes the shipped controller. It validates the seven-resource reference graph, drift repair, restart recovery, Observe adoption, connection Secrets, legacy cluster APIs and explicit empty role/scope revocation against Logto 1.40.1. Consent scope acceptance includes Terraform protocol CRUD/import, preservation of API consent grants, recovery when an initial write configured through initProvider fails, and explicit empty-list revocation with initialization defaults still present. These tests run through the existing make test-integration release gate. KUBEBUILDER_ASSETS must point to local etcd, kube-apiserver and kubectl binaries.

Connector configuration uses a SecretRef, and its sensitive JSON stays out of status. Required sensitive selectors in initProvider are omitted when unset so they cannot mask a valid forProvider selector. Singleton resources manage explicit JSON contracts, adopt external ID default, and never reset tenant configuration on deletion. Organizations, JWT customizer scripts, and SAML-specific settings are not managed yet. The validated Logto version is 1.40.1. CI includes real Logto/controller acceptance and amd64/arm64 package builds. Actual Crossplane Core installation and upgrade, production RBAC, load/soak testing and signed distribution remain release gates. Automatic credential rotation is not implemented.

Keep LateInitialize when creating resources whose IDs are assigned by Logto: the current Upjet async controller uses that policy to persist a generated external-name. Observe-only adoption supplies the existing external-name and does not need LateInitialize. Supply a connection Secret for sensitive state.

Upstream references: Terraform provider, Upjet template, Upjet, Logto application-secret API.

See quality assessment for executed checks, findings and production readiness gates.

Embedded dependency updates belong to the Terraform fork. Dependabot does not modify the snapshot directly: sync and review it after source dependency updates.

See operations and release gates for real acceptance, package verification, monitoring and recovery.

Package development

nix develop --command make package
GOARCH=arm64 nix develop --command make package

Each build creates .work/provider-upjet-logto.xpkg, runtime.spdx.json and SHA256SUMS. Packaging embeds the compiled controller, checks the non-root runtime, CA certificates and all 29 CRDs, and inventories dependencies with Syft. The local package builder does not need a container daemon.

License and provenance

This repository derives from the Apache-2.0 Upjet provider template; see LICENSE. The embedded Terraform fork retains its MIT license. Source ownership and upstream references are recorded in NOTICE.

About

Crossplane v2 provider for Logto, powered by Upjet with embedded Terraform Framework

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages