Skip to content

Commit

Permalink
Merge pull request #51 from Infisical/feature/oidc-machine-identity-r…
Browse files Browse the repository at this point in the history
…esource

feat: added identity oidc auth resource
  • Loading branch information
maidul98 authored Sep 15, 2024
2 parents a15c47d + cb8664f commit 5e56ae8
Show file tree
Hide file tree
Showing 7 changed files with 733 additions and 26 deletions.
80 changes: 80 additions & 0 deletions docs/resources/identity_oidc_auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "infisical_identity_oidc_auth Resource - terraform-provider-infisical"
subcategory: ""
description: |-
Create and manage identity oidc auth in Infisical.
---

# infisical_identity_oidc_auth (Resource)

Create and manage identity oidc auth in Infisical.

## Example Usage

```terraform
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}
provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}
resource "infisical_project" "example" {
name = "example"
slug = "example"
}
resource "infisical_identity" "machine-identity-1" {
name = "machine-identity-1"
role = "admin"
org_id = "<>"
}
resource "infisical_identity_oidc_auth" "oidc-auth" {
identity_id = infisical_identity.machine-identity-1.id
oidc_discovery_url = "<>"
bound_issuer = "<>"
bound_audiences = ["sample-audience"]
bound_subject = "<>"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `bound_issuer` (String) The unique identifier of the identity provider issuing the OIDC tokens.
- `identity_id` (String) The ID of the identity to attach the configuration onto.
- `oidc_discovery_url` (String) The URL used to retrieve the OpenID Connect configuration from the identity provider.

### Optional

- `access_token_max_ttl` (Number) The maximum lifetime for an access token in seconds. This value will be referenced at renewal time. Default: 2592000
- `access_token_num_uses_limit` (Number) The maximum number of times that an access token can be used; a value of 0 implies infinite number of uses. Default:0
- `access_token_trusted_ips` (Attributes List) A list of IPs or CIDR ranges that access tokens can be used from. You can use 0.0.0.0/0, to allow usage from any network address... (see [below for nested schema](#nestedatt--access_token_trusted_ips))
- `access_token_ttl` (Number) The lifetime for an access token in seconds. This value will be referenced at renewal time. Default: 2592000
- `bound_audiences` (List of String) The comma-separated list of intended recipients.
- `bound_claims` (Map of String) The attributes that should be present in the JWT for it to be valid. The provided values can be a glob pattern.
- `bound_subject` (String) The expected principal that is the subject of the JWT.
- `oidc_ca_certificate` (String) The PEM-encoded CA cert for establishing secure communication with the Identity Provider endpoints

### Read-Only

- `id` (String) The ID of the oidc auth.

<a id="nestedatt--access_token_trusted_ips"></a>
### Nested Schema for `access_token_trusted_ips`

Optional:

- `ip_address` (String)
33 changes: 33 additions & 0 deletions examples/resources/infisical_identity_oidc_auth/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
terraform {
required_providers {
infisical = {
# version = <latest version>
source = "infisical/infisical"
}
}
}

provider "infisical" {
host = "https://app.infisical.com" # Only required if using self hosted instance of Infisical, default is https://app.infisical.com
client_id = "<>"
client_secret = "<>"
}

resource "infisical_project" "example" {
name = "example"
slug = "example"
}

resource "infisical_identity" "machine-identity-1" {
name = "machine-identity-1"
role = "admin"
org_id = "<>"
}

resource "infisical_identity_oidc_auth" "oidc-auth" {
identity_id = infisical_identity.machine-identity-1.id
oidc_discovery_url = "<>"
bound_issuer = "<>"
bound_audiences = ["sample-audience"]
bound_subject = "<>"
}
91 changes: 91 additions & 0 deletions internal/client/identity_oidc_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package infisicalclient

import (
"fmt"
"net/http"
)

func (client Client) CreateIdentityOidcAuth(request CreateIdentityOidcAuthRequest) (IdentityOidcAuth, error) {
var body CreateIdentityOidcAuthResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Post("api/v1/auth/oidc-auth/identities/" + request.IdentityID)

if err != nil {
return IdentityOidcAuth{}, fmt.Errorf("CreateIdentityOidcAuth: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return IdentityOidcAuth{}, fmt.Errorf("CreateIdentityOidcAuth: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body.IdentityOidcAuth, nil
}

func (client Client) GetIdentityOidcAuth(request GetIdentityOidcAuthRequest) (IdentityOidcAuth, error) {
var body GetIdentityOidcAuthResponse

httpRequest := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT)

response, err := httpRequest.Get("api/v1/auth/oidc-auth/identities/" + request.IdentityID)

if response.StatusCode() == http.StatusNotFound {
return IdentityOidcAuth{}, ErrNotFound
}

if err != nil {
return IdentityOidcAuth{}, fmt.Errorf("GetIdentityOidcAuth: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return IdentityOidcAuth{}, fmt.Errorf("GetIdentityOidcAuth: Unsuccessful response. [response=%v]", string(response.Body()))
}

return body.IdentityOidcAuth, nil
}

func (client Client) UpdateIdentityOidcAuth(request UpdateIdentityOidcAuthRequest) (IdentityOidcAuth, error) {
var body UpdateIdentityOidcAuthResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Patch("api/v1/auth/oidc-auth/identities/" + request.IdentityID)

if err != nil {
return IdentityOidcAuth{}, fmt.Errorf("UpdateIdentityOidcAuth: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return IdentityOidcAuth{}, fmt.Errorf("UpdateIdentityOidcAuth: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body.IdentityOidcAuth, nil
}

func (client Client) RevokeIdentityOidcAuth(request RevokeIdentityOidcAuthRequest) (IdentityOidcAuth, error) {
var body RevokeIdentityOidcAuthResponse
response, err := client.Config.HttpClient.
R().
SetResult(&body).
SetHeader("User-Agent", USER_AGENT).
SetBody(request).
Delete("api/v1/auth/oidc-auth/identities/" + request.IdentityID)

if err != nil {
return IdentityOidcAuth{}, fmt.Errorf("RevokeIdentityOidcAuth: Unable to complete api request [err=%s]", err)
}

if response.IsError() {
return IdentityOidcAuth{}, fmt.Errorf("RevokeIdentityOidcAuth: Unsuccessful response. [response=%s]", string(response.Body()))
}

return body.IdentityOidcAuth, nil
}
117 changes: 93 additions & 24 deletions internal/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,23 @@ type IdentityKubernetesAuth struct {
TokenReviewerJwt string `json:"tokenReviewerJwt"`
}

type IdentityOidcAuth struct {
ID string `json:"id"`
AccessTokenTTL int64 `json:"accessTokenTTL"`
AccessTokenMaxTTL int64 `json:"accessTokenMaxTTL"`
AccessTokenNumUsesLimit int64 `json:"accessTokenNumUsesLimit"`
AccessTokenTrustedIPS []IdentityAuthTrustedIp `json:"accessTokenTrustedIps"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
IdentityID string `json:"identityId"`
OidcDiscoveryUrl string `json:"oidcDiscoveryUrl"`
BoundIssuer string `json:"boundIssuer"`
BoundAudiences string `json:"boundAudiences"`
BoundClaims map[string]string `json:"boundClaims"`
BoundSubject string `json:"boundSubject"`
CACERT string `json:"caCert"`
}

type IdentityAuthTrustedIp struct {
Type string `json:"type"`
Prefix *int `json:"prefix,omitempty"`
Expand Down Expand Up @@ -367,21 +384,21 @@ type EncryptedSecret struct {

// create secrets.
type CreateSecretV3Request struct {
SecretName string `json:"secretName"`
WorkspaceID string `json:"workspaceId"`
Type string `json:"type"`
Environment string `json:"environment"`
SecretKeyCiphertext string `json:"secretKeyCiphertext"`
SecretKeyIV string `json:"secretKeyIV"`
SecretKeyTag string `json:"secretKeyTag"`
SecretValueCiphertext string `json:"secretValueCiphertext"`
SecretValueIV string `json:"secretValueIV"`
SecretValueTag string `json:"secretValueTag"`
SecretCommentCiphertext string `json:"secretCommentCiphertext"`
SecretCommentIV string `json:"secretCommentIV"`
SecretCommentTag string `json:"secretCommentTag"`
SecretPath string `json:"secretPath"`
TagIDs []string `json:"tags"`
SecretName string `json:"secretName"`
WorkspaceID string `json:"workspaceId"`
Type string `json:"type"`
Environment string `json:"environment"`
SecretKeyCiphertext string `json:"secretKeyCiphertext"`
SecretKeyIV string `json:"secretKeyIV"`
SecretKeyTag string `json:"secretKeyTag"`
SecretValueCiphertext string `json:"secretValueCiphertext"`
SecretValueIV string `json:"secretValueIV"`
SecretValueTag string `json:"secretValueTag"`
SecretCommentCiphertext string `json:"secretCommentCiphertext"`
SecretCommentIV string `json:"secretCommentIV"`
SecretCommentTag string `json:"secretCommentTag"`
SecretPath string `json:"secretPath"`
TagIDs []string `json:"tags"`
}

// delete secret by name api.
Expand All @@ -395,15 +412,15 @@ type DeleteSecretV3Request struct {

// update secret by name api.
type UpdateSecretByNameV3Request struct {
SecretName string `json:"secretName"`
WorkspaceID string `json:"workspaceId"`
Environment string `json:"environment"`
Type string `json:"type"`
SecretPath string `json:"secretPath"`
SecretValueCiphertext string `json:"secretValueCiphertext"`
SecretValueIV string `json:"secretValueIV"`
SecretValueTag string `json:"secretValueTag"`
TagIDs []string `json:"tags,omitempty"`
SecretName string `json:"secretName"`
WorkspaceID string `json:"workspaceId"`
Environment string `json:"environment"`
Type string `json:"type"`
SecretPath string `json:"secretPath"`
SecretValueCiphertext string `json:"secretValueCiphertext"`
SecretValueIV string `json:"secretValueIV"`
SecretValueTag string `json:"secretValueTag"`
TagIDs []string `json:"tags,omitempty"`
}

// get secret by name api.
Expand Down Expand Up @@ -1196,6 +1213,58 @@ type UpdateIdentityKubernetesAuthRequest struct {
AccessTokenNumUsesLimit int64 `json:"accessTokenNumUsesLimit,omitempty"`
}

type CreateIdentityOidcAuthResponse struct {
IdentityOidcAuth IdentityOidcAuth `json:"identityOidcAuth"`
}

type UpdateIdentityOidcAuthResponse struct {
IdentityOidcAuth IdentityOidcAuth `json:"identityOidcAuth"`
}

type GetIdentityOidcAuthResponse struct {
IdentityOidcAuth IdentityOidcAuth `json:"identityOidcAuth"`
}

type GetIdentityOidcAuthRequest struct {
IdentityID string `json:"identityId"`
}

type RevokeIdentityOidcAuthRequest struct {
IdentityID string `json:"identityId"`
}

type RevokeIdentityOidcAuthResponse struct {
IdentityOidcAuth IdentityOidcAuth `json:"identityOidcAuth"`
}

type CreateIdentityOidcAuthRequest struct {
IdentityID string `json:"identityId"`
OidcDiscoveryUrl string `json:"oidcDiscoveryUrl"`
CACERT string `json:"caCert"`
BoundIssuer string `json:"boundIssuer"`
BoundAudiences string `json:"boundAudiences"`
BoundClaims map[string]string `json:"boundClaims"`
BoundSubject string `json:"boundSubject"`
AccessTokenTrustedIPS []IdentityAuthTrustedIpRequest `json:"accessTokenTrustedIps,omitempty"`
AccessTokenTTL int64 `json:"accessTokenTTL,omitempty"`
AccessTokenMaxTTL int64 `json:"accessTokenMaxTTL,omitempty"`
AccessTokenNumUsesLimit int64 `json:"accessTokenNumUsesLimit,omitempty"`
}

type UpdateIdentityOidcAuthRequest struct {
IdentityID string `json:"identityId"`
OidcDiscoveryUrl string `json:"oidcDiscoveryUrl"`
CACERT string `json:"caCert"`
BoundIssuer string `json:"boundIssuer"`
BoundAudiences string `json:"boundAudiences"`
BoundClaims map[string]string `json:"boundClaims"`
BoundSubject string `json:"boundSubject"`
AccessTokenTrustedIPS []IdentityAuthTrustedIpRequest `json:"accessTokenTrustedIps,omitempty"`
AccessTokenTTL int64 `json:"accessTokenTTL,omitempty"`
AccessTokenMaxTTL int64 `json:"accessTokenMaxTTL,omitempty"`
AccessTokenNumUsesLimit int64 `json:"accessTokenNumUsesLimit,omitempty"`
}

type UpdateIdentityKubernetesAuthResponse struct {
IdentityKubernetesAuth IdentityKubernetesAuth `json:"identityKubernetesAuth"`
}
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/strings/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package pkg

import "strings"

func StringSplitAndTrim(input string, seperator string) []string {
splittedStrings := strings.Split(input, seperator)
func StringSplitAndTrim(input string, separator string) []string {
splittedStrings := strings.Split(input, separator)
for i := 0; i < len(splittedStrings); i++ {
splittedStrings[i] = strings.TrimSpace(splittedStrings[i])
}
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,5 +247,6 @@ func (p *infisicalProvider) Resources(_ context.Context) []func() resource.Resou
infisicalResource.NewIdentityKubernetesAuthResource,
infisicalResource.NewIdentityGcpAuthResource,
infisicalResource.NewIdentityAzureAuthResource,
infisicalResource.NewIdentityOidcAuthResource,
}
}
Loading

0 comments on commit 5e56ae8

Please sign in to comment.