For Kubernetes or OpenShift deployments, the approach is completely different. In containerized environments, you don't use ILMT libraries at all. Instead, you use something called "metadata annotations."
What are annotations? Think of them as labels or tags that you attach to your containers. They are pieces of information that describe what's running inside the container. In this case, the annotations tell the system "this container is running BAMOE software" and provide the necessary details for license tracking.
This approach aligns with how cloud-native platforms work. Kubernetes and OpenShift use metadata extensively to manage, monitor, and govern applications. By using annotations for license tracking, BAMOE fits naturally into this ecosystem.
BAMOE Helm Charts: Automatic Annotations
Here's some great news: If you are deploying BAMOE components using Helm charts, you don't need to do anything. The annotations are already included automatically.
When you deploy Canvas, Management Console, or any other BAMOE component using the official Helm charts, the license tracking annotations are configured for you. This automation was introduced in BAMOE 9.4.0 and eliminates a common source of confusion. You can deploy with confidence knowing that license tracking is handled automatically.
Business Services and Custom Containers: Version-Controlled Approach
For Business Services and other custom containers you build yourself, we recommend a different approach that aligns with modern DevOps practices. Instead of adding annotations manually after deployment, you should define them directly in your version-controlled deployment YAML files.
Why is this important? Because it ensures that your deployment configuration - including the license tracking metadata - lives in your source control system alongside your application code. This approach provides several benefits:
- Version Control: Every change to your deployment configuration is tracked in Git
- Consistency: The same YAML file deploys identically across development, staging, and production
- Auditability: You can see who changed what and when
- Automation: Your CI/CD pipelines can validate that annotations are present before deployment
- Framework Independence: No dependency on application framework configuration files
Here's what the annotations look like in your deployment YAML:
kind: Deployment
apiVersion: apps/v1
metadata:
name: ${{ $.devDeployment.uniqueName }}
namespace: ${{ $.devDeployment.kubernetes.namespace }}
labels:
app: ${{ $.devDeployment.uniqueName }}
app.kubernetes.io/component: ${{ $.devDeployment.uniqueName }}
app.kubernetes.io/instance: ${{ $.devDeployment.uniqueName }}
app.kubernetes.io/name: ${{ $.devDeployment.uniqueName }}
app.kubernetes.io/part-of: ${{ $.devDeployment.uniqueName }}
spec:
replicas: 1
selector:
matchLabels:
app: ${{ $.devDeployment.uniqueName }}
template:
metadata:
annotations:
includeSWCUpload: true
productID: "<Product-ID>"
productName: "IBM Decision Manager Open Edition"
productMetric: "VIRTUAL_PROCESSOR_CORE"
productChargedContainers: "All"
labels:
app: ${{ $.devDeployment.uniqueName }}
deploymentconfig: ${{ $.devDeployment.uniqueName }}
spec:
containers:
- name: ${{ $.devDeployment.uniqueName }}
image: quay.io/bamoe/canvas-dev-deployment-base:9.4.0-ibm-0006-jdk21
imagePullPolicy: IfNotPresent
resources:
limits:
memory: "2048Mi"
ports:
- containerPort: 8080
protocol: TCP
env:
- name: DEV_DEPLOYMENT__UPLOAD_SERVICE_API_KEY
value: ${{ $.devDeployment.uploadService.apiKey }}
Important detail: Notice where the annotations are placed - under spec.template.metadata.annotations. This is crucial because it ensures that every pod created by this deployment carries the license tracking information. If you put the annotations in the wrong place, they won't work correctly.

Note: The example above shows annotations for IBM Decision Manager Open Edition (DMOE). For Process Automation Manager Open Edition (PAMOE), use the appropriate productID and productName values for your entitlement. Customers can choose the values as per their requirements. Please refer to the IBM Documentation for relevant information.
What is includeSWCUpload? This annotation enables your usage metrics to be uploaded to IBM Software Central, where they can be tracked and visualized. When set to true, the metrics collected by IBM License Service are automatically uploaded to Software Central dashboards. This provides visibility into your BAMOE usage patterns and helps with license management.
After you deploy, you can verify that the annotations are present using this command:
oc get pod -n bamoe-production -o jsonpath='{.metadata.annotations}'
This GitOps-aligned approach is now the recommended best practice for Business Services and custom containers.
Alternative: Manual Patching
There's also an alternative approach where you can add annotations to running deployments using the oc patch command. However, we don't recommend this as your primary method because changes made this way aren't captured in version control. If you redeploy your application, those manually added annotations could be lost.
Protecting Your Compliance: The Policy Enforcement Story
Now let's address a critical concern that many enterprise customers have raised: What prevents someone from accidentally - or even intentionally - removing these license tracking annotations?
This is a very real risk. Annotations are optional metadata. Anyone with deployment permissions in your Kubernetes or OpenShift cluster can modify or remove them. They might do this accidentally while troubleshooting, or they might not understand the importance of these annotations. Either way, if the annotations are removed, both you and IBM lose visibility into where BAMOE software is deployed. This makes license auditing difficult or impossible.
Why External Policy Enforcement?
The solution to this problem is external policy enforcement at the cluster level. This means using specialized tools that act as gatekeepers for your cluster. These tools examine every deployment before it's created and automatically reject any deployment that doesn't meet your requirements - in this case, deployments that lack the required license tracking annotations.
Two tools are particularly well-suited for this task:
Kyverno is a Kubernetes-native policy engine that works across all Kubernetes distributions, including OpenShift. It's widely adopted in enterprise environments and integrates seamlessly with existing infrastructure. Think of Kyverno as a security guard at the entrance to your cluster - it checks every deployment and only lets through those that follow the rules.
OpenShift Admission Policies are a native OpenShift capability available in version 4.17 and later. These policies integrate directly with OpenShift's admission control system, providing a platform-native solution for policy enforcement.
Why must enforcement be external? This is an important architectural principle. A container cannot reliably enforce its own policies because anyone with access to the container can bypass those self-imposed restrictions. It's like asking someone to guard themselves - it doesn't work. Policy enforcement must happen outside the application, at the infrastructure level, where it's controlled by IT and security teams rather than application developers.
Figure: External policy enforcement acting as a gatekeeper at the cluster level
Implementation Strategy: Namespace Scoping
Here's a practical question: How do you enforce policies for BAMOE deployments without breaking other applications running in your cluster?
The answer is namespace scoping. In Kubernetes and OpenShift, namespaces are like separate compartments within your cluster. By isolating BAMOE deployments into dedicated namespaces and applying policies only to those namespaces, you ensure that policy enforcement doesn't interfere with other applications.
You have two primary strategies for scoping policies:
Option 1: Label-Based Scoping (Opt-In Approach)
With this approach, you explicitly label specific namespaces to indicate they should be subject to BAMOE license tracking policies. This gives you fine-grained control - you decide exactly which namespaces are monitored.
Here's how you enable it:
# Create a namespace for BAMOE deployments
oc create namespace bamoe-production
# Label it to enable policy enforcement
oc label namespace bamoe-production audit-scope=true
Figure: Namespace labeled with audit-scope=true for policy enforcement
Your policy configuration then targets only namespaces with this label. Any namespace without the label is completely ignored by the policy, so your other applications continue to work normally.
This approach is ideal when you want explicit control over which namespaces are monitored. It requires a bit more manual work (you need to label each namespace), but it provides maximum flexibility.
Option 2: Pattern-Based Scoping (Automatic Approach)
With this approach, you establish a naming convention for BAMOE namespaces and use wildcard patterns to automatically apply policies. For example, you might decide that all BAMOE namespaces will start with bamoe-:
bamoe-production
bamoe-staging
bamoe-dev
bamoe-test
Your policy then uses a wildcard pattern to match these namespaces:
namespaces:
- "bamoe-*" # Automatically matches all namespaces starting with "bamoe-"
The beauty of this approach is that it's automatic. When you create a new namespace following the naming convention, it automatically inherits the policy enforcement without requiring manual labeling. This reduces administrative overhead and ensures consistency.
This approach is particularly useful for organizations with consistent naming conventions and multiple BAMOE environments. It's easier to manage at scale because you don't need to remember to label each new namespace.
How Policy Enforcement Works in Practice
Let's walk through what happens when someone tries to deploy an application:
Scenario 1: Deployment without annotations
A developer tries to deploy a Business Service but forgets to include the license tracking annotations. When they run the deployment command, the policy engine intercepts it, checks for the required annotations, doesn't find them, and immediately rejects the deployment:
Error: admission webhook denied the request
Deployment MUST include required audit annotations
Figure: Kyverno policy blocking a deployment that lacks required annotations
The deployment never gets created. The developer sees a clear error message explaining what's wrong, and they can fix it by adding the required annotations.
Scenario 2: Deployment with annotations
Another developer deploys a Business Service with the proper annotations included. The policy engine checks the deployment, finds all the required annotations, and allows it to proceed:
deployment.apps/my-business-service created
Figure: Deployment succeeds when all required annotations are present
The deployment succeeds, and the license tracking information is preserved.
This automatic validation happens for every deployment, every time, ensuring consistent compliance without requiring manual reviews.
Best Practices for Implementation
When implementing policy enforcement, follow these best practices:
Start in audit mode first: Before you enforce policies that block deployments, run them in audit mode. This means the policy will report violations but won't actually block anything. This gives you time to identify any issues and fix them before turning on enforcement.
Test in non-production environments: Deploy your policies to development or staging environments first. Test them thoroughly with sample deployments to make sure they work as expected and don't have unintended side effects.
Document your approach: Make sure your development teams understand which namespaces are subject to policies, what annotations are required, and how to troubleshoot issues when deployments are rejected. Clear documentation prevents frustration and speeds up adoption.
Exclude system namespaces: Make sure your policies don't interfere with critical system operations by excluding Kubernetes and OpenShift system namespaces from policy enforcement.
What You Gain from This Unified Approach
This new unified approach delivers significant benefits:
Clarity and Simplicity: Instead of navigating fragmented documentation, you have one clear path based on your deployment model. No more guessing which approach to use.
Automation Where It Matters: Helm charts include annotations automatically, eliminating manual configuration for standard BAMOE components. This reduces errors and saves time.
GitOps Alignment: The recommended approach for Business Services uses version-controlled YAML, which integrates seamlessly with modern CI/CD practices and provides full auditability.
Compliance Protection: External policy enforcement prevents unauthorized annotation removal, ensuring continuous compliance visibility. You can be confident that license tracking remains in place.
Reduced Risk: Clear guidance combined with automated enforcement minimizes the chance of compliance gaps. You're protected from both accidental and intentional removal of license tracking information.
Peace of Mind: You can focus on building great business automation solutions, knowing that license tracking is handled correctly and protected by policy enforcement.
Getting Started
Ready to implement this unified approach? The detailed documentation provides step-by-step instructions for:
- Setting up ILMT libraries for non-containerized deployments
- Configuring annotations in deployment YAML for Business Services
- Installing and configuring Kyverno on OpenShift
- Creating and testing policy enforcement rules
- Troubleshooting common issues
For complete implementation guidance, see the BAMOE documentation.
Additional Resources:
Summary
License tracking for BAMOE is now straightforward and aligned with modern deployment practices:
- Non-containerized deployments use ILMT compliance libraries that match your runtime and entitlement
- Containerized deployments use metadata annotations on Kubernetes resources
- BAMOE Helm charts include annotations automatically - no manual work required
- Business Services should define annotations in version-controlled deployment YAML for GitOps alignment
- Policy enforcement using Kyverno or OpenShift Admission Policies protects compliance by preventing unauthorized changes
This unified approach eliminates confusion, reduces implementation effort, and ensures reliable license tracking across all BAMOE deployment models. You get clear guidance, automated safeguards, and the confidence that your license compliance is properly managed.
Have questions about implementing license tracking or policy enforcement? The BAMOE team is here to help. Reach out through your usual support channels or explore our documentation for detailed, step-by-step guidance.