Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add shared_secret parameter to provider that creates a token for the bootstrap service account #5

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ go.work.sum
# env file
.env
.DS_Store
bin
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ lint:
@echo "@==> $@"
@VERSION=$$(go run github.com/mikefarah/yq/[email protected] '.jobs.lint.steps[] | select(.uses == "golangci/golangci-lint-action*") | .with.version' .github/workflows/test.yml) && \
go run github.com/golangci/golangci-lint/cmd/golangci-lint@$$VERSION run --fix --timeout=20m ./...

.PHONY: build
build:
@echo "@==> $@"
@go build -o bin/terraform-provider-pomerium
36 changes: 18 additions & 18 deletions example/main.tf
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
terraform {
required_providers {
pomerium = {
source = "github.com/pomerium/enterprise-terraform-provider"
version = "0.0.1"
}
required_providers {
pomerium = {
source = "pomerium/pomerium"
version = "0.0.1"
}
}

variable "pomerium_service_account_token" {
type = string
sensitive = true
}
}

provider "pomerium" {
api_url = "https://console-api.localhost.pomerium.io"
tls_insecure_skip_verify = true
service_account_token = var.pomerium_service_account_token
api_url = "https://console-api.localhost.pomerium.io"
tls_insecure_skip_verify = true
# service_account_token = var.pomerium_service_account_token
shared_secret_b64 = "9OkZR6hwfmVD3a7Sfmgq58lUbFJGGz4hl/R9xbHFCAg="
}

resource "pomerium_namespace" "test_namespace" {
name = "test-namespace"
parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
# resource "pomerium_namespace" "test_namespace" {
# name = "test-namespace"
# parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
# }

locals {
namespace_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
}

resource "pomerium_policy" "test_policy" {
name = "test-policy"
namespace_id = pomerium_namespace.test_namespace.id
namespace_id = local.namespace_id
ppl = <<EOF
- allow:
and:
Expand All @@ -35,7 +35,7 @@ EOF

resource "pomerium_route" "test_route" {
name = "test-route"
namespace_id = pomerium_namespace.test_namespace.id
namespace_id = local.namespace_id
from = "https://verify-tf.localhost.pomerium.io"
to = ["https://verify.pomerium.com"]
policies = [pomerium_policy.test_policy.id]
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/pomerium/enterprise-terraform-provider
go 1.23.0

require (
github.com/docker/cli v26.1.4+incompatible
github.com/go-jose/go-jose/v3 v3.0.3
github.com/hashicorp/terraform-plugin-framework v1.11.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/pomerium/enterprise-client-go v0.18.1-0.20240903154554-9b855ec72cfd
Expand All @@ -22,7 +22,6 @@ require (
github.com/envoyproxy/go-control-plane v0.13.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand Down
42 changes: 42 additions & 0 deletions internal/provider/bootstrap_service_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package provider

import (
"encoding/base64"
"fmt"
"time"

"github.com/go-jose/go-jose/v3"
"github.com/go-jose/go-jose/v3/jwt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func generateBootstrapServiceAccountToken(
sharedSecretB64 string,
) (string, error) {
sharedSecret, err := base64.StdEncoding.DecodeString(sharedSecretB64)
if err != nil {
return "", fmt.Errorf("shared_secret is invalid: %w", err)
}

sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: sharedSecret},
(&jose.SignerOptions{}).WithType("JWT"))
if err != nil {
return "", status.Errorf(codes.Internal, "signing JWT: %s", err.Error())
}

var claims struct {
jwt.Claims
}
claims.ID = "014e587b-3f4b-4fcf-90a9-f6ecdf8154af"
claims.Subject = "bootstrap-014e587b-3f4b-4fcf-90a9-f6ecdf8154af.pomerium"
now := time.Now()
claims.IssuedAt = jwt.NewNumericDate(now)
claims.NotBefore = jwt.NewNumericDate(now)

rawJWT, err := jwt.Signed(sig).Claims(claims).CompactSerialize()
if err != nil {
return "", status.Errorf(codes.Internal, "signing JWT: %s", err.Error())
}
return rawJWT, nil
}
2 changes: 1 addition & 1 deletion internal/provider/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (r *NamespaceResource) Schema(_ context.Context, _ resource.SchemaRequest,
},
"parent_id": schema.StringAttribute{
Description: "ID of the parent namespace (optional).",
Optional: false,
Optional: true,
},
},
}
Expand Down
26 changes: 20 additions & 6 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type PomeriumProvider struct {
type PomeriumProviderModel struct {
APIURL types.String `tfsdk:"api_url"`
ServiceAccountToken types.String `tfsdk:"service_account_token"`
SharedSecretB64 types.String `tfsdk:"shared_secret_b64"`
TLSInsecureSkipVerify types.Bool `tfsdk:"tls_insecure_skip_verify"`
}

Expand All @@ -49,7 +50,12 @@ func (p *PomeriumProvider) Schema(_ context.Context, _ provider.SchemaRequest, r
},
"service_account_token": schema.StringAttribute{
MarkdownDescription: "Pomerium Enterprise Service Account Token",
Required: true,
Optional: true,
Sensitive: true,
},
"shared_secret_b64": schema.StringAttribute{
MarkdownDescription: "Pomerium Shared Secret (base64 encoded)",
Optional: true,
Sensitive: true,
},
"tls_insecure_skip_verify": schema.BoolAttribute{
Expand Down Expand Up @@ -88,13 +94,21 @@ func (p *PomeriumProvider) Configure(ctx context.Context, req provider.Configure
port = "443"
}

if data.ServiceAccountToken.IsNull() {
resp.Diagnostics.AddError("service_account_token is required", "service_account_token is required")
tlsConfig := &tls.Config{InsecureSkipVerify: data.TLSInsecureSkipVerify.ValueBool()}
var token string
if !data.ServiceAccountToken.IsNull() {
token = data.ServiceAccountToken.ValueString()
} else if !data.SharedSecretB64.IsNull() {
token, err = generateBootstrapServiceAccountToken(data.SharedSecretB64.ValueString())
if err != nil {
resp.Diagnostics.AddError("failed to decode shared_secret_b64", err.Error())
return
}
} else {
resp.Diagnostics.AddError("service_account_token or shared_secret_b64 is required", "service_account_token or shared_secret_b64 is required")
return
}

tlsConfig := &tls.Config{InsecureSkipVerify: data.TLSInsecureSkipVerify.ValueBool()}
c, err := client.NewClient(ctx, net.JoinHostPort(host, port), data.ServiceAccountToken.ValueString(), client.WithTlsConfig(tlsConfig))
c, err := client.NewClient(ctx, net.JoinHostPort(host, port), token, client.WithTlsConfig(tlsConfig))
if err != nil {
resp.Diagnostics.AddError("failed to create Pomerium Enterprise API client", err.Error())
return
Expand Down
Loading