OpenShift Service Accounts
Learn how Service Accounts work in OpenShift, understand application identity, authentication, API access, RBAC integration, and secure Spring Boot applications using Service Accounts.
Introduction
When developers log in to OpenShift, they authenticate using a User Account.
However, applications running inside Pods are not human users. They also need an identity to:
- Read ConfigMaps
- Access Secrets
- Call the Kubernetes API
- Communicate with other OpenShift resources
- Authenticate securely without hardcoded credentials
This identity is called a Service Account.
Every Pod running inside OpenShift executes using a Service Account.
Instead of embedding usernames and passwords inside applications, OpenShift automatically provides secure authentication through Service Accounts.
Learning Objectives
By the end of this article, you will understand:
- What is a Service Account?
- Why Service Accounts are required
- Service Account architecture
- Default Service Account
- Creating custom Service Accounts
- RBAC integration
- Spring Boot API access
- Enterprise security best practices
Why Service Accounts?
Imagine a Spring Boot application that needs to read a ConfigMap.
Without a Service Account:
flowchart LR
A[Spring Boot]
--> B[Kubernetes API]
B --> C[❌ Authentication Failed]
The Kubernetes API doesn't know the application's identity.
Solution
Assign a Service Account.
flowchart LR
A[Spring Boot Pod]
--> B[Service Account]
B --> C[Kubernetes API]
C --> D[ConfigMaps]
C --> E[Secrets]
The application now has a secure identity.
What is a Service Account?
A Service Account is a Kubernetes/OpenShift resource that provides an identity for Pods.
Unlike a User Account:
| User Account | Service Account |
|---|---|
| Human | Application |
| Interactive Login | Automatic Authentication |
| OAuth / LDAP | Kubernetes Token |
| Used by Developers | Used by Pods |
Service Account Architecture
flowchart TD
Pod[Spring Boot Pod]
SA[Service Account]
API[Kubernetes API]
Secrets[Secrets]
ConfigMaps[ConfigMaps]
Pod --> SA
SA --> API
API --> Secrets
API --> ConfigMaps
Authentication Flow
sequenceDiagram
participant Pod
participant ServiceAccount
participant KubernetesAPI
participant Secret
Pod->>ServiceAccount: Request Token
ServiceAccount->>KubernetesAPI: Authenticate
KubernetesAPI-->>Pod: Authentication Success
Pod->>Secret: Read Secret
Default Service Account
Every namespace automatically contains a default Service Account.
Verify:
oc get serviceaccounts
Example:
NAME
default
builder
deployer
OpenShift automatically assigns the default Service Account unless another one is specified.
Built-in Service Accounts
| Service Account | Purpose |
|---|---|
| default | Application Pods |
| builder | BuildConfig builds |
| deployer | Deployment operations |
View Service Accounts
oc get sa
Describe:
oc describe sa default
Create Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: payment-service-account
Deploy:
oc apply -f service-account.yaml
Verify Service Account
oc get serviceaccounts
Example:
NAME
default
payment-service-account
Assign Service Account
Deployment YAML
spec:
template:
spec:
serviceAccountName: payment-service-account
Every Pod created from this Deployment uses the specified Service Account.
Deployment Architecture
flowchart LR
Deployment
--> Pod1
Deployment
--> Pod2
Pod1
--> ServiceAccount
Pod2
--> ServiceAccount
Service Account Token
Each Service Account receives a secure authentication token.
flowchart LR
ServiceAccount
--> Token
Token
--> KubernetesAPI
The token is automatically mounted inside the Pod.
Token Location
Inside the Pod:
/var/run/secrets/kubernetes.io/serviceaccount/
Files include:
token
namespace
ca.crt
Verify Token
Open Pod.
oc rsh payment-api-xxxxx
View:
ls /var/run/secrets/kubernetes.io/serviceaccount
Spring Boot Example
Suppose the application needs to read ConfigMaps.
Dependency:
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
</dependency>
Read ConfigMap
KubernetesClient client =
new KubernetesClientBuilder().build();
ConfigMap configMap =
client.configMaps()
.inNamespace("payments")
.withName("payment-config")
.get();
Authentication happens automatically using the mounted Service Account token.
Service Account + RBAC
A Service Account has no permissions by default.
Permissions are granted using RBAC.
flowchart LR
ServiceAccount
--> RoleBinding
RoleBinding
--> Role
Role
--> ConfigMaps
Create Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: config-reader
rules:
- apiGroups: [""]
resources:
- configmaps
verbs:
- get
- list
Create RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: payment-binding
subjects:
- kind: ServiceAccount
name: payment-service-account
roleRef:
kind: Role
name: config-reader
apiGroup: rbac.authorization.k8s.io
Permission Flow
flowchart LR
SpringBoot
--> ServiceAccount
ServiceAccount
--> RoleBinding
RoleBinding
--> Role
Role
--> ConfigMaps
Banking Example
flowchart TD
PaymentService
--> PaymentSA[Payment Service Account]
PaymentSA
--> PaymentSecrets
PaymentSA
--> PaymentConfig
PaymentSA
-. Cannot Access .-> LoanNamespace
Every microservice has its own Service Account.
Microservice Architecture
flowchart LR
PaymentService
--> PaymentSA
CustomerService
--> CustomerSA
NotificationService
--> NotificationSA
PaymentSA
--> PaymentSecrets
CustomerSA
--> CustomerSecrets
NotificationSA
--> NotificationSecrets
Applications have isolated identities.
Service Account Isolation
Never share one Service Account across unrelated applications.
flowchart TD
PaymentApp
--> PaymentSA
CustomerApp
--> CustomerSA
InventoryApp
--> InventorySA
This minimizes security risks.
Verify Current Service Account
oc describe pod payment-api
Look for:
Service Account:
payment-service-account
Check Permissions
oc auth can-i get configmaps \
--as system:serviceaccount:payments:payment-service-account
Expected:
yes
Common Problems
Forbidden Error
Example:
Error from server (Forbidden)
Possible causes:
- Missing Role
- Missing RoleBinding
- Wrong Service Account
Service Account Not Used
Check Deployment.
oc describe deployment payment-api
Verify:
serviceAccountName
Cannot Read Secrets
Verify RBAC.
oc auth can-i get secrets
Enterprise Architecture
flowchart TD
USERS["Users"]
ROUTE["OpenShift Route"]
GATEWAY["API Gateway"]
PAYMENT["Payment Service"]
SA["Payment Service Account"]
CONFIG["ConfigMaps"]
SECRETS["Secrets"]
DB["PostgreSQL"]
USERS --> ROUTE
ROUTE --> GATEWAY
GATEWAY --> PAYMENT
PAYMENT --> SA
SA --> CONFIG
SA --> SECRETS
PAYMENT --> DB
Best Practices
- Create one Service Account per microservice.
- Follow the Principle of Least Privilege.
- Avoid using the default Service Account in production.
- Grant only required permissions.
- Rotate Service Account tokens where applicable.
- Audit Service Account permissions regularly.
- Never grant cluster-admin to applications.
- Use separate Service Accounts for CI/CD pipelines.
Common Mistakes
❌ Using the default Service Account for every application.
❌ Sharing one Service Account across multiple services.
❌ Granting excessive permissions.
❌ Embedding Kubernetes credentials inside source code.
❌ Using cluster-admin for application Pods.
Advantages
- Secure application identity
- Automatic authentication
- RBAC integration
- Least-privilege access
- Better auditing
- No hardcoded credentials
- Enterprise security
- Cloud-native authentication
Summary
Service Accounts provide the identity that applications use inside OpenShift.
Key takeaways:
- Every Pod runs using a Service Account.
- Service Accounts authenticate applications to the Kubernetes API.
- RBAC controls what a Service Account can access.
- Each microservice should have its own dedicated Service Account.
- Avoid using the default Service Account for production workloads.
- Combining Service Accounts with RBAC creates a secure and scalable authorization model.
Interview Questions
- What is a Service Account?
- Why do applications need Service Accounts?
- What is the difference between a User Account and a Service Account?
- Where is the Service Account token mounted inside a Pod?
- How do you assign a Service Account to a Deployment?
- How are permissions granted to a Service Account?
- Why should every microservice have its own Service Account?
- What are the built-in Service Accounts in OpenShift?
- How do you verify the Service Account used by a Pod?
- What are the best practices for using Service Accounts?