Native Shell
Native Shell은 모든 플랫폼의 앱 안에서 만들어지는 AI UI입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A lightweight Kubernetes operator that provisions Keycloak realms, groups, users, and OAuth clients declaratively via CRDs.
Applications can request their own Keycloak configuration without manual Keycloak admin access or pre-deploy scripts.
The operator manages four CRD kinds:
| Kind | What it provisions |
|---|---|
KeycloakRealm | A Keycloak realm |
KeycloakRealmGroup | A group within a realm, with optional realm-role assignments |
KeycloakUser | A user within a realm, with optional group membership and role assignments |
KeycloakClient | An OAuth client within a realm, with a generated secret stored in a K8s Secret |
All resources are reconciled continuously — the operator detects and repairs out-of-band drift every 5 minutes.
KeycloakRealm
└── KeycloakRealmGroup (ownerRef → Realm; cascade-deleted with realm)
└── KeycloakUser (ownerRef → Realm; cascade-deleted with realm)
└── KeycloakClient (ownerRef → Realm; cascade-deleted with realm)
└── K8s Secret (ownerRef → Client; GC'd with client)
Deleting a KeycloakRealm CR triggers K8s garbage collection of all child CRs, which in turn clean up their Keycloak resources before the realm itself is deleted.
Add the Helm repository:
helm repo add keycloak-provisioner https://drewsonne.github.io/keycloak-provisioner
helm repo update
Install the chart:
helm install keycloak-provisioner keycloak-provisioner/keycloak-provisioner \
--namespace keycloak \
--set keycloak.url=http://keycloak.keycloak.svc.cluster.local \
--set keycloak.adminSecret.name=keycloak-admin-credentials
apiVersion: v1
kind: Secret
metadata:
name: keycloak-admin-credentials
namespace: keycloak
stringData:
username: admin
password: <admin-password>
Default values:
image:
repository: drewsonne/keycloak-provisioner
tag: latest
keycloak:
url: http://keycloak-keycloakx-http.keycloak.svc.cluster.local
adminSecret:
name: keycloak-admin-credentials
namespace: keycloak
Creates a Keycloak realm with configurable login, security, and SSL settings.
apiVersion: keycloak.drewsonne.github.io/v1
kind: KeycloakRealm
metadata:
name: my-realm
namespace: keycloak
spec:
realm: my-realm
displayName: My Realm
enabled: true
loginWithEmailAllowed: true
bruteForceProtected: true
sslRequired: external # none | external | all
sslRequired values:
| Value | Behaviour |
|---|---|
none | SSL is not required for any client IP address |
external | Non-private IP addresses must use SSL |
all | All IP addresses must use SSL |
Creates a group within a realm, with optional realm-role assignments and custom attributes.
apiVersion: keycloak.drewsonne.github.io/v1
kind: KeycloakRealmGroup
metadata:
name: my-realm-admins
namespace: keycloak
spec:
realm: my-realm
name: admins
realmRoles:
- admin
attributes:
team: ["platform"]
Creates a user within a realm, with optional group membership and realm-role assignments.
apiVersion: keycloak.drewsonne.github.io/v1
kind: KeycloakUser
metadata:
name: alice
namespace: keycloak
spec:
realm: my-realm
username: alice
email: [email protected]
firstName: Alice
lastName: Smith
enabled: true
emailVerified: true
groups:
- admins
realmRoles:
- offline_access
Creates an OAuth client within a realm, with a generated secret stored in a K8s Secret. Supports protocol mappers for token claim customisation.
apiVersion: keycloak.drewsonne.github.io/v1
kind: KeycloakClient
metadata:
name: my-app
namespace: my-app
spec:
clientId: my-app
realm: my-realm
redirectUris:
- https://my-app.example.com/oauth-callback
webOrigins:
- https://my-app.example.com
secretName: keycloak-my-app-secret
secretNamespace: my-app # optional; defaults to CR namespace
protocolMappers:
- name: realm-roles
mapperType: oidc-usermodel-realm-role-mapper
config:
multivalued: "true"
userinfo.token.claim: "true"
id.token.claim: "true"
access.token.claim: "true"
claim.name: "realm_access.roles"
jsonType.label: "String"
Every CR accepts an optional keycloakAdminSecret field to use a different Keycloak admin account (useful for multi-tenant setups):
spec:
keycloakAdminSecret:
name: my-other-admin-secret
namespace: keycloak
KeycloakClient creates a Secret containing:
client_id — the Keycloak client IDclient_secret — the OAuth client secretkubectl get secret keycloak-my-app-secret -n my-app -o yaml
KeycloakClient Secret already exists, the client_secret is preserved rather than regeneratedkubectl describe as a K8s Warning event and in the Drift printer columnKeycloakRealm CR triggers cleanup of all child CRs (groups, users, clients) before the realm is removed from KeycloakKeycloakUser references a group that doesn't exist yet, the controller retries automatically until the group is readykubectl get keycloakrealms
kubectl get keycloakclients
kubectl get keycloakrealmgroups
kubectl get keycloakusers
Printer columns include Ready, Drift, and Age. Drift events are also emitted as Kubernetes Warning events visible via kubectl describe.
Build locally:
docker build -t drewsonne/keycloak-provisioner:dev .
Run locally (requires cluster access):
docker run --rm \
-e KEYCLOAK_URL=http://keycloak.keycloak.svc.cluster.local \
-e KEYCLOAK_ADMIN_USERNAME=admin \
-e KEYCLOAK_ADMIN_PASSWORD=... \
drewsonne/keycloak-provisioner:dev
GPLv3