Skip to content

feat(ncp): implement direct IAM token generation for NKS clusters#1645

Merged
powerkimhub merged 1 commit intocloud-barista:masterfrom
hanizang77:250122-k8s
Feb 2, 2026
Merged

feat(ncp): implement direct IAM token generation for NKS clusters#1645
powerkimhub merged 1 commit intocloud-barista:masterfrom
hanizang77:250122-k8s

Conversation

@hanizang77
Copy link
Copy Markdown
Contributor

@hanizang77 hanizang77 commented Jan 26, 2026

Implement Direct IAM Token Generation for NCP NKS Clusters

Summary

This PR implements direct NCP IAM token generation using HMAC-SHA256 signatures for NCP NKS (Naver Kubernetes Service) cluster authentication. The token is embedded directly in the kubeconfig, providing a streamlined authentication experience using only CB-Spider's CredentialInfo.

Solution

Direct Token Generation

This implementation generates NCP IAM tokens directly within the driver using:

  • HMAC-SHA256 Signature: Based on NCP IAM authentication protocol
  • CB-Spider CredentialInfo: Uses existing ClientId (AccessKey) and ClientSecret (SecretKey)
  • Embedded Token: Token is directly included in kubeconfig, no external commands needed

New kubeconfig Format

users:
- name: nks_KR_cluster_uuid
  user:
    token: k8s-ncp-v1.eyJ0aW1lc3RhbXAiOiIxNzY5NDE3MTA3MTkyIiwiYWNjZXNzS2V5IjoibmNwX2lhbV9CUEFTS1JJOG94MXYzTHY2dWpMcCIsInNpZ25hdHVyZSI6IkxialhnQzFOWkdpUTBJaU5yMGpEa3NHTGxjT0V0NjhrNk1HbjRkbTkxODA9IiwicGF0aCI6Ii9pYW0vdjEvdXNlcj9jbHVzdGVyVXVpZD1mZWJjYTc4OS00ZjMyLTQ0MDUtOTFiNS02OTcwZTQ4ZmIyNmIifQ==

Technical Implementation

Token Generation Algorithm

The NCP IAM token follows this structure:

k8s-ncp-v1.{base64(json(claim))}

Where the claim contains:

{
  "timestamp": "1769417107192",
  "accessKey": "ncp_iam_EXAMPLE_KEY_xxxxxxxxxxxx",
  "signature": "LbjXgC1NZGiQ0IiNr0jDksGLlcOEt68k6MGn4dm9180=",
  "path": "/iam/v1/user?clusterUuid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Signature Generation

The signature is created using HMAC-SHA256:

signature = HMAC-SHA256(
  secretKey,
  "GET {path}\n{timestamp}\n{accessKey}"
)

Token Expiration

  • Tokens are valid for 15 minutes from the timestamp
  • A new token is generated on each GetCluster() call
  • Kubernetes clients will automatically refresh tokens as needed

Code Changes

Modified Files

  1. ClusterHandler.go (~1965 lines)

    • Added CredentialInfo field to NcpVpcClusterHandler struct
    • Implemented generateNCPIAMToken() function (main token generation)
    • Implemented makeNCPSignature() function (HMAC-SHA256 signing)
    • Implemented getNCPIAMPath() function (API path construction)
    • Implemented getNCPRegionStage() function (region to stage mapping)
    • Modified addIAMAuthentication() to use direct token generation instead of exec
    • Added ncpTokenClaim struct for JSON serialization
  2. NcpVpcCloudConnection.go

    • Modified CreateClusterHandler() to pass CredentialInfo to ClusterHandler

New Dependencies

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/base64"
    "encoding/json"
)

Key Functions

generateNCPIAMToken()

func generateNCPIAMToken(accessKey, secretKey, clusterUUID, ncpRegion string) (string, error)
  • Main entry point for token generation
  • Constructs timestamp, path, and signature
  • Assembles final token in k8s-ncp-v1.{claim} format

makeNCPSignature()

func makeNCPSignature(method, path, timestamp, accessKey, secretKey string) (string, error)
  • Generates HMAC-SHA256 signature
  • Returns base64-encoded signature string

getNCPRegionStage()

func getNCPRegionStage(region string) string
  • Maps NCP region codes to IAM authentication API stages
  • Based on official ncp-iam-authenticator implementation
  • Supported regions:
    • KR (Korea) → v1
    • SGN (Singapore) → sgn-v1
    • JPN (Japan) → jpn-v1
    • KRS (Korea South, future) → krs-v1
    • F* (Finance regions) → v1
    • CS (Cloud Stack regions) → v1
    • Unknown regions → {region}-v1 (automatic fallback)

Note: The v1 in IAM path (/iam/v1/user) is different from NKS API version (/vnks/v2):

  • /iam/v1/user?clusterUuid=xxx - IAM authentication endpoint (used for token signature)
  • /vnks/v2/clusters - NKS management API endpoint (used for cluster operations)

Testing Results

Environment

  • Cluster Version: Kubernetes 1.33.4-nks.1
  • Region: Korea (KR)
  • Node: 1 worker node (s4-g3 spec)
  • Status: RUNNING

Authentication Test

$ kubectl cluster-info
Kubernetes control plane is running at https://febca789-4f32-4405-91b5-6970e48fb26b.kr.vnks.ntruss.com

$ kubectl get nodes
NAME              STATUS   ROLES    AGE   VERSION
ng-ssjua-w-8961   Ready    <none>   23m   v1.33.4

Namespace & Pod Test

$ kubectl get ns
NAME              STATUS   AGE
default           Active   29m
kube-node-lease   Active   29m
kube-public       Active   29m
kube-system       Active   29m

$ kubectl get pods -A
NAMESPACE     NAME                                     READY   STATUS    RESTARTS   AGE
kube-system   cilium-d6f9h                             1/1     Running   0          23m
kube-system   cilium-operator-86d785cbbb-8wgcz         1/1     Running   0          28m
kube-system   coredns-7984cd47f4-q5pwp                 1/1     Running   0          26m
kube-system   csi-nks-controller-775dbdc75f-tb2xw      6/6     Running   0          26m
... (all pods running successfully)

nginx Deployment Test

Deployment Creation

$ kubectl create deployment nginx --image=nginx:latest
deployment.apps/nginx created

$ kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed

Deployment Status

$ kubectl get deployment nginx
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           64s

$ kubectl get pods -l app=nginx -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE
nginx-54c98b4f84-w4pc4   1/1     Running   0          34s   198.18.0.33   ng-ssjua-w-8961

Service Configuration

$ kubectl get svc nginx
NAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx   NodePort   198.19.255.235   <none>        80:32309/TCP   10s

$ kubectl describe svc nginx
Type:                     NodePort
IP:                       198.19.255.235
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  32309/TCP
Endpoints:                198.18.0.33:80

nginx Access Test (Pod Internal)

$ kubectl exec -it deployment/nginx -- curl -s localhost | head -5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

nginx Access Test (ClusterIP via DNS)

$ kubectl run curl-test --image=curlimages/curl:latest --rm -i --restart=Never \
  -- curl -s nginx.default.svc.cluster.local | head -5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

Test Results Summary

Authentication: Successfully authenticated using generated NCP IAM token
Cluster Info: Retrieved cluster information and node status
Resource Management: Created and managed Deployments, Services, Pods
Networking: ClusterIP and NodePort services working correctly
DNS Resolution: CoreDNS service discovery functioning properly
Pod Scheduling: Pods scheduled and running on worker nodes
Application Deployment: nginx deployment fully operational

Comparison with Other CSP Implementations

AWS EKS

  • Uses StsClient to generate presigned URLs
  • Token embedded in kubeconfig (similar approach)

GCP GKE

  • Uses CredentialInfo for OAuth2 JWT tokens
  • Token embedded in kubeconfig (similar approach)

NCP NKS (This Implementation)

  • Uses CredentialInfo for HMAC-SHA256 presigned tokens
  • Token embedded in kubeconfig (consistent with AWS/GCP)
  • Similar approach to AWS and GCP drivers for unified credential management

Breaking Changes

None. This is a transparent implementation change:

  • API remains unchanged
  • Existing kubeconfig files will be regenerated with new format on next GetCluster() call
  • No user action required beyond using CB-Spider credentials

References

- Add generateNCPIAMToken() with HMAC-SHA256 signature
- Embed tokens directly in kubeconfig (no external CLI needed)
- Use CredentialInfo.ClientId/ClientSecret for token generation
- Add region-to-stage mapping based on official ncp-iam-authenticator
@powerkimhub powerkimhub merged commit 9495b85 into cloud-barista:master Feb 2, 2026
3 checks passed
@hanizang77 hanizang77 deleted the 250122-k8s branch February 2, 2026 06:28
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.

2 participants