Skip to content

feat: add project_id support to ory_json_web_key_set resource#129

Closed
KT-Doan wants to merge 1 commit intomainfrom
KevinTDoan/jwk-project-id
Closed

feat: add project_id support to ory_json_web_key_set resource#129
KT-Doan wants to merge 1 commit intomainfrom
KevinTDoan/jwk-project-id

Conversation

@KT-Doan
Copy link
Copy Markdown
Collaborator

@KT-Doan KT-Doan commented Mar 17, 2026

Description

Adds project_id support to the ory_json_web_key_set resource, resolving the issue where users couldn't create JWK sets using project_id-based workflows.

The resource now accepts an optional project_id attribute that auto-resolves the project slug via the console API, eliminating the need to manually configure project_slug on the provider for JWK operations.

Related Issues

Fixes #120

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Checklist

  • I have read the CONTRIBUTING guide
  • My code follows the existing code style
  • I have added tests that prove my fix/feature works
  • I have updated documentation as needed
  • All new and existing tests pass (make test)
  • I have run the linter (make format)

Testing

  • Unit tests (make test-short — all pass)
  • Acceptance tests (make test-accTestAccJWKResource_basic passes with create, read, and composite import)
  • Security scans (make sec && make sec-trivy — 0 issues)
  • Manual testing

Changes

Client (internal/client/client.go):

  • ResolveProjectSlug(ctx, projectID) — resolves project ID to slug via console API
  • ProjectClientForProject(ctx, projectID) — returns a project-scoped client for a given project ID

Resource (internal/resources/jwk/resource.go):

  • Added project_id attribute (optional, computed, requires replace)
  • CRUD operations resolve the project client from project_id
  • Import supports both project_id/set_id and plain set_id formats

Tests, docs, examples updated to demonstrate project_id usage.

Screenshots/Output

=== RUN   TestAccJWKResource_basic
    acctest.go:132: Using pre-created test project: 3fa274fe-... (slug: sad-moser-..., environment: prod)
--- PASS: TestAccJWKResource_basic (6.27s)

The JWK resource previously required project_slug and project_api_key
on the provider, with no way to specify project_id at the resource
level. This made it impossible to use with project_id-based workflows.

Changes:
- Add optional project_id attribute to ory_json_web_key_set (falls back
  to provider's project_id when not set)
- Add ResolveProjectSlug and ProjectClientForProject methods to the
  client for resolving project_id to slug via the console API
- Support composite import format: project_id/set_id
- Update acceptance tests, examples, and documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 17, 2026 05:06
@KT-Doan KT-Doan closed this Mar 17, 2026
@KT-Doan KT-Doan deleted the KevinTDoan/jwk-project-id branch March 17, 2026 05:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds project_id support to the ory_json_web_key_set Terraform resource by resolving project slugs via the console API, enabling project-id-based workflows and composite import IDs.

Changes:

  • Add project_id attribute to the JWK resource and resolve a project-scoped client from it.
  • Extend import to accept project_id/set_id in addition to set_id.
  • Update acceptance test config, examples, and docs to demonstrate project_id usage.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
templates/resources/json_web_key_set.md.tmpl Docs template updated for immutability note and composite import format.
internal/resources/jwk/testdata/basic.tf.tmpl Acceptance test template now sets project_id.
internal/resources/jwk/resource_test.go Acceptance test updated to pass project_id and import using composite ID.
internal/resources/jwk/resource.go Adds project_id to schema; resolves project-scoped client; updates import parsing.
internal/client/client.go Adds console-based project slug resolution and project-scoped client factory.
examples/resources/ory_json_web_key_set/resource.tf Example updated to show provider-scoped vs explicit project_id.
docs/resources/json_web_key_set.md Generated docs updated for immutability note, examples, import format, and new attribute.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

// resolveProjectID returns the project ID from the resource attribute or falls back to the provider's project_id.
func (r *JWKResource) resolveProjectID(tfProjectID types.String) string {
if !tfProjectID.IsNull() && !tfProjectID.IsUnknown() {
return tfProjectID.ValueString()
Comment on lines 26 to +37
func TestAccJWKResource_basic(t *testing.T) {
projectID := os.Getenv("ORY_PROJECT_ID")

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.AccPreCheck(t) },
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories(),
Steps: []resource.TestStep{
// Create and Read
{
Config: acctest.LoadTestConfig(t, "testdata/basic.tf.tmpl", nil),
Config: acctest.LoadTestConfig(t, "testdata/basic.tf.tmpl", map[string]string{
"ProjectID": projectID,
}),
Comment on lines 311 to +329
func (r *JWKResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("set_id"), req.ID)...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), req.ID)...)
// Import ID format: project_id/set_id or just set_id (uses provider's project_id)
id := req.ID
var projectID, setID string

if strings.Contains(id, "/") {
parts := strings.SplitN(id, "/", 2)
projectID = parts[0]
setID = parts[1]
} else {
setID = id
}

resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("set_id"), setID)...)
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), setID)...)
if projectID != "" {
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), projectID)...)
}
}
Comment on lines +457 to +484
// ResolveProjectSlug resolves a project ID to its slug via the console API.
// This allows resources to accept project_id and auto-resolve the slug needed
// for project API operations (e.g., JWK, OAuth2).
func (c *OryClient) ResolveProjectSlug(ctx context.Context, projectID string) (string, error) {
if c.consoleClient == nil {
return "", fmt.Errorf("console API client not configured: workspace_api_key is required to resolve project_id to slug")
}
project, err := c.GetProject(ctx, projectID)
if err != nil {
return "", fmt.Errorf("resolving project slug for project %s: %w", projectID, err)
}
return project.GetSlug(), nil
}

// ProjectClientForProject returns a project-scoped client for the given project ID.
// It resolves the project slug via the console API and uses the provider's project API key.
func (c *OryClient) ProjectClientForProject(ctx context.Context, projectID string) (*OryClient, error) {
slug, err := c.ResolveProjectSlug(ctx, projectID)
if err != nil {
return nil, err
}
apiKey := c.config.ProjectAPIKey
if apiKey == "" {
return nil, fmt.Errorf("project_api_key is required for project API operations (JWK, OAuth2, etc.): " +
"set it on the provider or via ORY_PROJECT_API_KEY environment variable")
}
return c.WithProjectCredentials(slug, apiKey), nil
}
## Import

Import using the set ID:
Import using the format `project_id/set_id` or just `set_id` (uses provider's project_id):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing project-id input for json_web_key_set terraform resource

2 participants