Skip to content

fix: resolve nil pointer dereference when creating OAuth2 client with unknown provider config#68

Merged
KT-Doan merged 3 commits intomainfrom
fix/oauth2-client-nil-pointer-deref
Feb 24, 2026
Merged

fix: resolve nil pointer dereference when creating OAuth2 client with unknown provider config#68
KT-Doan merged 3 commits intomainfrom
fix/oauth2-client-nil-pointer-deref

Conversation

@KT-Doan
Copy link
Collaborator

@KT-Doan KT-Doan commented Feb 24, 2026

Description

Fixes a nil pointer dereference crash when creating an ory_oauth2_client resource whose provider credentials (project_slug, project_api_key) reference resources being created in the same terraform apply. Terraform marks such values as "unknown" during provider configuration, leaving the internal projectClient nil and causing a panic on the first API call.

This PR adds lazy initialization for the project API client and introduces resource-level credential attributes so that ory_oauth2_client can be created in the same apply as the project it belongs to.

Changes

internal/client/client.go

  • Add ensureProjectClient() with mutex-protected lazy initialization, called as a guard in all 20+ methods that use projectClient
  • Add SetProjectCredentials(slug, apiKey) to allow runtime credential injection from resource-level attributes
  • Returns a clear error message instead of crashing when credentials are missing
  • Extract schemeHTTPS/schemeHTTP constants to satisfy goconst linter

internal/resources/oauth2client/resource.go

  • Add optional project_slug and project_api_key schema attributes
  • Call SetProjectCredentials() before API calls in Create, Read, Update, and Delete

Documentation & Examples

  • Add "Resource-Level Credentials" section to templates/resources/oauth2_client.md.tmpl
  • Add same-apply example to examples/resources/ory_oauth2_client/resource.tf

Related Issues

Fixes #56

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 — 7 new tests for ensureProjectClient() and SetProjectCredentials() (34 total, all pass)
  • Acceptance tests — 1 new TestAccOAuth2ClientResource_withResourceCredentials test; all 8 OAuth2 client acceptance tests pass against staging
  • Manual testing — reproduced the original crash, verified the fix returns a clear error, and tested full lifecycle (create/refresh/destroy) with resource-level credentials

Screenshots/Output

Before (crash):

panic: runtime error: invalid memory address or nil pointer dereference
  client.go:767 in (*OryClient).CreateOAuth2Client

After (clear error when credentials missing):

Error: project API client not configured: project_slug and project_api_key are required.
Set them on the provider or pass them as resource-level attributes (project_slug, project_api_key)

Acceptance tests:

--- PASS: TestAccOAuth2ClientResource_basic (3.67s)
--- PASS: TestAccOAuth2ClientResource_withAudience (2.38s)
--- PASS: TestAccOAuth2ClientResource_withRedirectURIs (2.32s)
--- PASS: TestAccOAuth2ClientResource_withNewFields (2.52s)
--- PASS: TestAccOAuth2ClientResource_withConsentAndSubjectType (2.52s)
--- PASS: TestAccOAuth2ClientResource_withJWKS (3.54s)
--- PASS: TestAccOAuth2ClientResource_withResourceCredentials (2.61s)
--- PASS: TestAccOAuth2ClientResource_withTokenLifespans (2.47s)
PASS
ok  	github.com/ory/terraform-provider-ory/internal/resources/oauth2client	22.403s

… unknown provider config

Add lazy initialization for the project API client to handle the case where
provider credentials (project_slug, project_api_key) reference resources being
created in the same apply. Previously this caused a nil pointer dereference
because Terraform marks such values as "unknown" during provider configuration.

Changes:
- Add ensureProjectClient() guard with mutex to all projectClient methods
- Add SetProjectCredentials() for runtime credential injection
- Add resource-level project_slug and project_api_key attributes to
  ory_oauth2_client for same-apply scenarios
- Extract scheme constants to satisfy goconst linter

Fixes #56
Copilot AI review requested due to automatic review settings February 24, 2026 12:58
@KT-Doan KT-Doan self-assigned this Feb 24, 2026
Copy link
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

This pull request fixes a nil pointer dereference that occurred when creating an ory_oauth2_client resource whose provider credentials reference resources being created in the same terraform apply. When Terraform marks such values as "unknown" during provider configuration, the internal projectClient remained nil, causing a panic on the first API call. The fix introduces lazy initialization for the project API client with clear error messaging, and adds optional resource-level credential attributes to enable same-apply project and client creation.

Changes:

  • Added lazy initialization with ensureProjectClient() method guarding all 20+ project API client usages
  • Added SetProjectCredentials() to allow runtime credential injection from resource-level attributes
  • Added optional project_slug and project_api_key attributes to ory_oauth2_client schema

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/client/client.go Adds lazy initialization (ensureProjectClient) and credential setter (SetProjectCredentials) with mutex protection; adds guards to all project client methods; extracts URL scheme constants
internal/client/client_test.go Adds 7 unit tests covering lazy initialization, credential setting, re-initialization, and missing credential scenarios
internal/resources/oauth2client/resource.go Adds project_slug and project_api_key schema attributes; adds setResourceCredentials helper; calls credential setter in all CRUD operations
internal/resources/oauth2client/resource_test.go Adds acceptance test for resource-level credentials feature
internal/resources/oauth2client/testdata/with_resource_credentials.tf.tmpl Test configuration template for resource-level credentials
templates/resources/oauth2_client.md.tmpl Adds "Resource-Level Credentials" documentation section with example
examples/resources/ory_oauth2_client/resource.tf Adds same-apply example demonstrating resource-level credentials
docs/resources/oauth2_client.md Generated documentation updates with new attributes and examples

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

Replace the mutable SetProjectCredentials method with WithProjectCredentials
that returns a new isolated OryClient. This eliminates shared state mutation
and race conditions when multiple resources use different credentials.

The new client shares the console API client with its parent but has its own
project API client (lazily initialized), ensuring thread safety.
Copy link
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

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


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

Comment on lines +124 to +134
# Same-apply: Create project and OAuth2 client together
# Use resource-level credentials when the project doesn't exist yet
resource "ory_oauth2_client" "same_apply" {
project_slug = ory_project.main.slug
project_api_key = ory_project_api_key.main.value

client_name = "Created with Project"
grant_types = ["client_credentials"]
token_endpoint_auth_method = "client_secret_post"
scope = "api:read api:write"
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

The example references ory_project.main and ory_project_api_key.main resources that are not defined in this file. For a complete, working example, these resource definitions should be included. Consider adding:

resource "ory_project" "main" {
  name        = "my-project"
  environment = "prod"
}

resource "ory_project_api_key" "main" {
  project_id = ory_project.main.id
  name       = "terraform-key"
}

before the ory_oauth2_client resource, or add a comment noting that these resources need to be defined elsewhere.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@Demonsthere Demonsthere left a comment

Choose a reason for hiding this comment

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

lgtm

@KT-Doan KT-Doan merged commit 09038b1 into main Feb 24, 2026
17 of 19 checks passed
@KT-Doan KT-Doan deleted the fix/oauth2-client-nil-pointer-deref branch February 24, 2026 14:02
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.

Getting a server crash when trying to create oauth client resource

3 participants