# Welcome

Welcome to **Krutrim Cloud** — a full-stack cloud platform purpose-built for the AI era.

We are an **AI infrastructure-first** company, reimagining cloud computing to meet the demands of developers, researchers, and enterprises building next-generation AI applications. From high-performance GPUs to AI-native container orchestration, Krutrim Cloud delivers the flexibility, power, and simplicity required to build, deploy, and scale complex workloads — all from within a unified, India-first ecosystem.

Whether you're training foundation models, deploying inference at scale, or managing large distributed systems, Krutrim provides you with the essential building blocks of modern infrastructure.

***

### What We Offer

Krutrim Cloud spans the entire stack of infrastructure services needed for today’s AI and compute-heavy workloads:

<table><thead><tr><th width="176.52734375">Service</th><th>Information</th></tr></thead><tbody><tr><td><strong>Compute</strong></td><td>Launch CPU and GPU virtual machines, GPU bare metal servers, and Kubernetes-managed AI Pods for container-based workflows.</td></tr><tr><td><strong>Storage</strong></td><td>Leverage scalable and secure block and object storage, with support for volumes, snapshots, and backups for persistent data management.</td></tr><tr><td><strong>Networking</strong></td><td>Build and isolate cloud networks with VPCs, subnets, security groups, and elastic IPs.</td></tr><tr><td><strong>AI Studio</strong></td><td>Access a powerful catalogue of opensource and frontier AI models, available for inference, training, deployment, and evaluation through an intuitive interface and APIs.</td></tr><tr><td><strong>SDK</strong></td><td>Interact programmatically with the Krutrim platform through robust SDKs for developers and DevOps teams.</td></tr></tbody></table>

***

### Built in India, for India

We are deeply committed to enabling digital sovereignty and self-reliance in cloud infrastructure. Krutrim Cloud is designed to serve Indian developers, startups, and enterprises with:

* **Lower latency** and regional presence
* **Data locality** and compliance alignment
* **Affordable pricing** and transparent billing

Our mission is to democratize access to cutting-edge cloud infrastructure, making it easier and more efficient for builders across the country to scale AI solutions without dependency on international hyperscalers.

### Jump right in

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Quickstart</strong></td><td>Create your first VM</td><td><a href="/pages/wKqIiZHP9bmC5OiwHXJp">/pages/wKqIiZHP9bmC5OiwHXJp</a></td></tr></tbody></table>


# Quickstart

### Core Infrastructure

In Core-Infrastructure, you can either&#x20;

* Create a Virtual Machine to run your workload, or
* Create an AI Pod to run your AI workload or&#x20;

**Create a Virtual Machine to run your workload**

To create any virtual machine, you first need to set up your network settings, like VPC, Subnet, IP addresses, and Security Groups, so that you can isolate your workloads properly

1. Create your first VPC to securely isolate your workload. You can create your subnet along with the VPC. Create a public subnet if you want your VM to be accessible from the public. [Learn More](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/networking/vpc)
2. If you want any specific subnet configuration, create a subnet. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/networking/subnets)
3. If you want your VMs to be accessible to the public, you would need to reserve a public IP. You can also assign a random public IP while creating the VM. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/networking/static-ip-addresses)
4. You also need to create a security group to control your ingress and Egress traffic. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/networking/security-groups)
5. You will need to create an SSH key to access your VMs. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/compute/ssh-key)
6. Please create the respective bootable and storage volumes to run your workloads. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/storage/block-storage/volumes)
7. Now you can create a VM after all these steps with the respective configurations of CPU or GPU. [Learn more](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/compute/vms-and-baremetals)

**Create an AI Pod to run your AI workload**

AI Pod is Krutrim's revolutionary first-in-the-world containerised GPU splices with Ephemeral and Persistent storage, ideal for AI workloads

You can create your first AI Pod by referring [here](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/compute/ai-pods)


# Managing your Krutrim Cloud Account

This document outlines how to manage your Krutrim Cloud account, including updating profile information, resetting your password, and initiating account deletion. Maintaining an accurate and complete profile ensures seamless access to services, proper billing, and effective support.

***

### Registering on the Cloud Platform

Follow these steps to create a new Krutrim Cloud account:

1. Navigate to the [**Krutrim Cloud Sign Up Page**](https://cloud.olakrutrim.com/signUp)
2. Enter your personal details, including **Full Name**, **Email Address**, and **Mobile Number**
3. Select a secure password following these rules:
   * At least **12 characters** long
   * Contains at least **one uppercase letter**
   * Contains at least **one lowercase letter**
   * Contains at least **one number**
   * Contains at least **one special character**
4. Click **Sign Up**. You will receive **unique OTP codes** on both your phone and email
5. Complete **OTP verification** for both your phone number and email address
6. Select your **Account Type**:
   * **Individual** – for personal accounts
   * **Organization** – for business or institutional accounts
7. Provide the required details based on your selected account type
8. Review all information for accuracy and click **Save** to complete your registration
9. Once your registration is complete, you can log in to the **Krutrim Cloud Console** and start using the platform

{% hint style="danger" %}
**Note:** Please ensure that your name (and organization name, if applicable) matches your official documents, as the platform will soon introduce identity verification for existing as well as new accounts
{% endhint %}

### Profile Management

The profile page allows you to view and update personal or organizational information linked to your Krutrim Cloud account. Depending on your account type—Individual or Organization—you will have access to different fields. Certain fields are view-only and cannot be edited for security and compliance reasons.

#### **Steps to Update Your Profile**

To update your personal or organization details on Krutrim Cloud:

1. **Log in** to your Krutrim Cloud Account.
2. Navigate to the **"My Account"** section in the dashboard.
3. Click on **“My Account”** to view your current account information.
4. Review your details:
   * Editable fields will appear as input boxes or dropdowns.
   * Non-editable fields (like email or account type) will be grayed out.
5. Make the desired updates to the editable fields
6. Once all changes are made, click **“Save”**
7. A confirmation message will appear once the changes are successfully saved.

{% hint style="success" %}
**Best Practices:**

* Ensure your name and address are accurate for billing and invoicing
* Avoid frequent changes to profile data to prevent billing or support discrepancies
* Keep your profile complete to enable personalized support and services
  {% endhint %}

### Password Management&#x20;

Password management is an essential part of securing your Krutrim Cloud account. This section outlines how to update your password from within the platform and how to reset it if you've lost access. Following recommended password practices helps protect your account from unauthorized access and ensures continued access to services.

#### **Steps to Update Your Account Password**

You can update your current password through the Profile page using the following steps:

1. Log in to your Krutrim Cloud account.
2. Navigate to the Account page.
3. Click on Change Password button.
4. Enter your current password.
5. Enter and confirm your new password.
6. Save your changes to ensure your password is updated

#### Resetting a Forgotten Password

If you've forgotten your Krutrim Cloud password, follow these steps to reset your password:

1. Navigate to the **Krutrim Cloud Login** page.
2. Click on **“Forgot Password?”**
3. Enter your **registered email address**. If the provided address matches an existing account, a password reset link will be sent to your inbox
4. Check your inbox for a **password reset link** sent to the email address provided.
5. Click the link and follow the prompts to **set a new password**.

{% hint style="warning" %}
**Note:** Password reset links are only valid for 60 minutes
{% endhint %}

### Deleting your Krutrim Account and Associated Data

To request the deletion of your Krutrim Cloud account and all associated data, please contact our support team by emailing **<cloudsupport@olakrutrim.com>**. Ensure that your request includes your registered Account ID to help us process it efficiently.

{% hint style="danger" %}
**Important:** Account deletion is irreversible. You will lose access to all services and stored data as per our data retention policy.
{% endhint %}


# Navigating the Console

Will be completed once 2A changes are live on prod


# Core Infrastructure

Krutrim Cloud delivers the foundational infrastructure required to build, deploy, and scale modern workloads. Our platform is designed to offer high performance, flexibility, and reliability across three primary service pillars:

* **Compute** – Provision CPU and GPU virtual machines, Kubernetes-based AI Pods, and dedicated GPU baremetal instances to power everything from general-purpose workloads to high-performance AI/ML training and inferencing.
* **Storage** – Store and manage data efficiently with **Block Storage** for high-performance persistent volumes and **Object Storage** for scalable, cost-effective data storage.
* **Networking** – Build secure, isolated environments using **VPCs**, define **subnets**, assign **IP addresses**, and configure **security groups** to control traffic flows and access.

This core infrastructure forms the backbone for running applications, training AI models, hosting services, and managing enterprise-scale workloads on Krutrim Cloud.


# Compute

Krutrim Cloud provides a range of compute options designed to meet the demands of modern workloads—from general-purpose virtual machines to high-performance GPU clusters for large-scale AI training. Whether you are building web applications, running simulations, or deploying complex machine learning models, our compute infrastructure is engineered for performance, scalability, and transparency.

***

### Available Compute Services

Krutrim Cloud offers four categories of compute services:

<table><thead><tr><th width="193.09375">Service</th><th>Description</th></tr></thead><tbody><tr><td><strong>CPU Virtual Machines</strong></td><td>General-purpose VMs for development environments, web applications, and backend services</td></tr><tr><td><strong>GPU Virtual Machines</strong></td><td>Ideal for model training, batch inference, and high-performance computing workflows</td></tr><tr><td><strong>GPU Baremetals</strong></td><td>Dedicated, non-virtualized GPU machines for full control over drivers, kernels, and performance tuning</td></tr><tr><td><strong>AI Pods</strong></td><td>Kubernetes-native GPU compute for orchestrated AI workloads including training, fine-tuning, and inference</td></tr></tbody></table>

***

### 1. CPU Virtual Machines

Krutrim’s CPU VMs are powered by AMD EPYC 9554 processors and come with scalable vCPU-RAM configurations, suitable for a wide range of workloads.

| Flavor        | vCPU / RAM       | Unit | On-Demand Price | Monthly Reserved | 6 Month Reserved |
| ------------- | ---------------- | ---- | --------------- | ---------------- | ---------------- |
| CPU-1x-4GB    | 1 vCPU / 4 GB    | Hour | ₹3.00           | ₹2.85            | ₹2.70            |
| CPU-2x-8GB    | 2 vCPU / 8 GB    | Hour | ₹6.00           | ₹5.70            | ₹5.40            |
| CPU-4x-16GB   | 4 vCPU / 16 GB   | Hour | ₹13.00          | ₹12.35           | ₹11.70           |
| CPU-8x-32GB   | 8 vCPU / 32 GB   | Hour | ₹25.00          | ₹23.75           | ₹22.50           |
| CPU-16x-64GB  | 16 vCPU / 64 GB  | Hour | ₹49.00          | ₹46.55           | ₹44.10           |
| CPU-32x-128GB | 32 vCPU / 128 GB | Hour | ₹97.00          | ₹92.15           | ₹87.30           |

### 2. GPU Virtual Machines

GPU VMs offer virtualized access to NVIDIA A100 and H100 GPUs. These instances are suited for intensive compute use cases such as model training, inference serving, and simulation workloads.

| GPU Flavor          | GPU Type / Count | RAM (GB) | GPU Memory (GB) | vCPUs | Unit | On-Demand Price | Monthly Reserved | 6 Month Reserved |
| ------------------- | ---------------- | -------- | --------------- | ----- | ---- | --------------- | ---------------- | ---------------- |
| A100-80GB-NVLINK-1x | A100 80GB ×1     | 96       | 80              | 24    | Hour | ₹189            | ₹148             | ₹132             |
| H100-NVLINK-1x      | H100 ×1          | 200      | 80              | 24    | Hour | ₹213            | ₹198             | ₹186             |
| H100-NVLINK-2x      | H100 ×2          | 400      | 160             | 48    | Hour | ₹426            | ₹396             | ₹372             |
| H100-NVLINK-4x      | H100 ×4          | 800      | 320             | 96    | Hour | ₹852            | ₹792             | ₹744             |

***

### 3. GPU Baremetals

Baremetal GPU instances provide direct access to powerful NVIDIA GPUs without the abstraction of virtualization. These are ideal for users who require advanced GPU configurations, low-level control, and high throughput.

***

### 4. AI Pods

AI Pods offer a Kubernetes-native GPU compute environment, allowing you to run distributed AI workloads such as model training, evaluation, inference, and MLOps workflows. These are managed clusters provisioned with pre-configured GPU compute SKUs.

| Flavor                  | GPU Config  | RAM (GB) | GPU Memory (GB) | vCPUs | Unit | On-Demand Price |
| ----------------------- | ----------- | -------- | --------------- | ----- | ---- | --------------- |
| A100-NVLINK-Tiny        | A100 (Tiny) | 30       | 5               | 16    | Hour | ₹24.00          |
| A100-NVLINK-Nano        | A100 (Nano) | 60       | 10              | 16    | Hour | ₹49.00          |
| A100-NVLINK-Mini        | A100 (Mini) | 60       | 20              | 16    | Hour | ₹73.00          |
| A100-NVLINK-Standard-1x | A100 ×1     | 60       | 40              | 16    | Hour | ₹170.00         |
| A100-NVLINK-Standard-2x | A100 ×2     | 125      | 80              | 16    | Hour | ₹340.00         |
| A100-NVLINK-Standard-4x | A100 ×4     | 250      | 160             | 128   | Hour | ₹510.00         |
| A100-NVLINK-Standard-8x | A100 ×8     | 1000     | 320             | 128   | Hour | ₹1,360.00       |
| H100-NVLINK-Tiny        | H100 (Tiny) | 60       | 10              | 16    | Hour | ₹30.00          |
| H100-NVLINK-Nano        | H100 (Nano) | 60       | 20              | 16    | Hour | ₹61.00          |
| H100-NVLINK-Mini        | H100 (Mini) | 60       | 40              | 16    | Hour | ₹91.00          |
| H100-NVLINK-Standard-1x | H100 ×1     | 125      | 80              | 16    | Hour | ₹213.00         |
| H100-NVLINK-Standard-2x | H100 ×2     | 250      | 160             | 52    | Hour | ₹425.00         |
| H100-NVLINK-Standard-4x | H100 ×4     | 1004     | 320             | 104   | Hour | ₹850.00         |
| H100-NVLINK-Standard-8x | H100 ×8     | 2008     | 640             | 208   | Hour | ₹1,700.00       |

| Storage Type   | Flavor         | Unit | Price / GB / Hour | Price / GB / Month |
| -------------- | -------------- | ---- | ----------------- | ------------------ |
| Ephemeral-SSD  | Ephemeral-SSD  | Hour | ₹0.006            | ₹4.38              |
| Persistent-SSD | Persistent-SSD | Hour | ₹0.006            | ₹4.38              |


# VMs & Baremetals

Krutrim Cloud offers high-performance **Virtual Machines (VMs)** for compute workloads, including GPU-powered VMs for AI/ML tasks and CPU-based machines for general-purpose use. Users can customize, monitor, and manage their machines with flexible volume and networking configurations.

{% hint style="info" %}
Network speed - All our Virtual Machines support up to **10 Gbps network speed**.
{% endhint %}

***

### Creating a VM <a href="#creating-a-vm" id="creating-a-vm"></a>

To create a new virtual machine:

1. Navigate to the **VM configurations** page and click **“Reserve”** next to your preferred setup.
2. On the creation form, configure the following fields:

#### Required Fields <a href="#required-fields" id="required-fields"></a>

* **Name**: Unique name for your machine (e.g., `vm-ai-builder`).
* **VPC**: Select a VPC based on the region of the selected VM. You can also create a new VPC in the same region directly from this interface.
* **Volumes**:
  * **Bootable volumes** (required)
  * Optional: **Storage volumes**
* **SSH Key**: Upload or paste your public SSH key for secure terminal access.
  * Learn how to create and connect your SSH key [here](https://krutrim-cloud-documentation.gitbook.io/krutrim-cloud-documentation/~/revisions/d4NYBPQU0HIXDoAQnCSW/basics/compute/ssh-key).
* **Startup Script**: Optional. Bash scripts only. This is the script that will run every time your Machine starts
* **Tags**: Add custom tags for VM identification and billing filters.
* **Price Summary**: A live cost summary based on your configuration.

#### 💡 Note: <a href="#note" id="note"></a>

> To attach a reserved IP or control network access (ports), configure them in the **Advanced Settings** section.

### Advanced Settings <a href="#advanced-settings" id="advanced-settings"></a>

#### Subnet <a href="#subnet" id="subnet"></a>

* Select from existing subnets within the selected VPC.
* New subnets can be created (preselected VPC).
* If no subnet is selected, a **default public subnet** is attached silently.

#### IP Address Type <a href="#ip-address-type" id="ip-address-type"></a>

* Shown only if a **public subnet** is selected in the previous settings
* Choose between:
  * **Floating IP** – Dynamic, assigned from IP pool. Reassigned on restart.
  * **Reserved IP** – Static, retains the same IP across restarts.
* If “Reserved IP” is selected, choose from unassigned reserved IPs in the dropdown.

#### &#x20;Security Group <a href="#security-group" id="security-group"></a>

* Select from existing Security Groups under the selected VPC.
* New groups can be created here (VPC pre-selected).
* If no group is selected, then no traffic will be allowed in/out of the machine

{% hint style="warning" %}
Please note that Port 22 or the SSH protocol should be enabled if you want to SSH into the VMs
{% endhint %}

***

### &#x20;Attaching & Detaching a Volume <a href="#attaching-and-detaching-a-volume" id="attaching-and-detaching-a-volume"></a>

Volumes can be attached or detached after VM creation via the **My Machines** page.

#### &#x20;Attaching a Volume <a href="#attaching-a-volume" id="attaching-a-volume"></a>

1. Click the **three-dot menu (⋮)** for the target VM.
2. Select **Attach/Detach Volumes**.
3. Click "Change Bootable volumes" if you want to change the bootable volume or "Attach Storage volumes" if you want to attach a storage volume
4. A pop-up will show all **active, unattached volumes within the same VPC**.
5. Choose volumes to attach/change and confirm.
6. A prompt will notify:

   **The VM has to be restarted to attach the volume. Confirm restart to proceed.**
7. Once attached, volumes are attached/changed

#### Detaching a Volume <a href="#detaching-a-volume" id="detaching-a-volume"></a>

1. Click the **three-dot menu (⋮)** and choose **Attach/Detach Volumes**.
2. Bootable volumes can't be detached; they can only be changed.
3. Click "Change Bootable volumes" if you want to change the bootable volume
4. To detach a storage volume, click on the "Delete" icon near the storage volume
5. Confirm the warning:

   **The VM has to be restarted to detach the volume. Confirm restart to proceed.**

⚠️ One VM can be attached to multiple volumes, but each volume can only be attached to one VM at a time.

***

### Editing a VM <a href="#editing-a-vm" id="editing-a-vm"></a>

VMs can be edited for network and SSH configurations. To edit a VM:

1. Go to **My Machines**.
2. Click the **three-dot menu (⋮)** > **Edit VM**.
3. Editable fields:
   * Description
   * Tags

***

### Attaching/Detaching Security group <a href="#connecting-to-the-machine" id="connecting-to-the-machine"></a>

Only one security group can be attached to a VM at a time

**Attach/change/detach security group**

1. Click on the three dots
2. Click on "Attach/detach security group"
3. The currently attached security group, if any, will be visible here
4. If you want to change/detach the security group, click on the "detach" button
5. A confirmation pop-up will appear. Once confirmed, the currently attached security group will be detached. Please note that once a security group is detached, no traffic in/out to/from your VM will be allowed
6. Click on attach if you want to attach a new one.
7. Select from the existing security groups which one you want to attach
8. Give confirmation, and the security group will be attached

***

### Attaching/Detaching Public IP address <a href="#connecting-to-the-machine" id="connecting-to-the-machine"></a>

1. Click on the three dots
2. Click on Attach/detach Public IP
3. If there are any attached Public IPs, they will be mentioned there.
   1. If no Public IPs are attached, then click on attach IP and select from the reserved IP, or assign a random floating IP to your VM
   2. Please note that the private IP will also change once you change/attach a new IP
4. Click on delete, which will then open up a confirmation pop-up. Once confirmed, the Public IP will be detached
5. Click on attach IP and select from the reserved IP, or assign a random floating IP to your VM
   1. Please note that the private IP will also change once you change/attach a new IP

***

### Creating Machine Image <a href="#connecting-to-the-machine" id="connecting-to-the-machine"></a>

Machine image is a way for you to reuse your current VMs to easily make more copies of it

1. Click on the three dots
2. Click on "Create Machine Image"
3. Enter the name of the Image
4. Click on create. This will create a Machine Image for your VM immediately

***

### Connecting to the Machine <a href="#connecting-to-the-machine" id="connecting-to-the-machine"></a>

Once the VM is active:

1. Use an SSH client (e.g., OpenSSH, PuTTY).
2. Run the command:

   `bash`

   CopyEdit

   `ssh -i <path-to-your-private-key> ubuntu@<public-ip>`

   Example:

   `bash`

   CopyEdit

   `ssh -i ~/.ssh/my-key.pem ubuntu@206.1.53.62`

Upon connection, you're ready to interact with your virtual machine.

***

### Stopping/Restarting a VM <a href="#my-machines-page" id="my-machines-page"></a>

1. Click on the three dots
2. Click on "Stop Machine"
3. A confirmation pop-up will appear. Once confirmed, the VM will be stopped.
   1. You won't be charged for the VM when it's stopped. Only the volumes will be charged during this duration
   2. Please note that there's no guarantee that you can get the same VM configuration once stopped
4. To restart, click on the three dots and click on restart VM
5. This will restart the VM

***

### Rebooting a VM <a href="#my-machines-page" id="my-machines-page"></a>

1. Click on the three dots
2. Click on "Reboot VM"
3. A confirmation pop-up will appear. Once confirmed, the VM will be rebooted

***

### Terminating a VM <a href="#my-machines-page" id="my-machines-page"></a>

1. Click on the three dots
2. Click on "Terminate VM"
3. A confirmation pop-up will appear. Once confirmed, the VM will be terminated, and the VM will not be accessible anymore

### My Machines Page <a href="#my-machines-page" id="my-machines-page"></a>

This dashboard allows you to view and manage all your VMs.

#### 🔎 Table Overview <a href="#table-overview" id="table-overview"></a>

* **Machine Name**: Unique identifier (e.g., `vm_test`)
* **Public IP**: External IP for remote access
* **Status**: Active / Stopped
* **Actions (⋮)**:
  * How to Connect
  * Stop Machine
  * Reboot
  * Terminate Machine

#### 🔍 Machine Details (on click) <a href="#machine-details-on-click" id="machine-details-on-click"></a>

* **Start Time**
* **Configuration**: e.g., `CPU-1x-4GB`
* **Hours Utilized**: e.g., `00 d : 02 h : 15 min`

You can manage machine state, view usage details, or initiate secure connections from this panel.

***

### Billing

You will be charged for the VM as long as it is active (running). If your machine is stopped or paused, or terminated, then it won’t be charged.

<br>


# Custom Firewall

**UFW Firewall Setup on Ubuntu VM**

You can attach a UFW firewall to your VMs. **Enabling the UFW firewall may break SSH access to your VM or other open ports.**&#x50;lease follow these steps to ensure SSH access is maintained.

***

#### Solution

When enabling a firewall on a remote server that you connect to using SSH, make sure to **adjust the default policy to allow connections** instead of the default deny. Otherwise, enabling the firewall could disconnect your remote session and disable access to the server.

***

#### Step-by-Step Instructions

#### Step 1: Set the default policy to allow

Run the following command to set the default policy to allow all connections. This will prevent being locked out once the firewall is enabled:

```
sudo ufw default allow
```

#### Step 2: Enable the firewall

Enable the firewall with the following command. This will apply the settings:

```
1sudo ufw enable
```

#### Step 3: Allow SSH access (Port 22)

Use the following command to allow incoming TCP connections on port 22 (the default SSH port):

```
1sudo ufw allow 22/tcp
```

#### Step 4: Set the default policy to deny

Once SSH access is allowed, you can change the default policy to deny all incoming connections. This makes your server more secure by only allowing traffic on explicitly open ports:

```
1sudo ufw default deny
```

Following these steps ensures that SSH access remains available while securing your VM with the UFW firewall.

<br>


# EasyDeploy

Deploy pre-configured AI environments on Krutrim Cloud with one-click templates like OpenClaw and Jupyter Notebook.

Krutrim EasyDeploy lets you launch pre-configured AI environments on Krutrim Cloud with one-click templates. It provisions a Virtual Machine with the required software stack, dependencies, runtimes, and application code already installed.

EasyDeploy currently supports two templates:

* OpenClaw: A pre-configured environment for deploying autonomous AI agents.
* Jupyter Notebook: A ready-to-use workspace for data science and model experimentation.

| Template Name    | Use Case          | Default Port | VM Name Prefix |
| ---------------- | ----------------- | ------------ | -------------- |
| OpenClaw         | Autonomous Agents | 443 (HTTPS)  | openclaw\_     |
| Jupyter Notebook | Data Science / ML | 8888 (HTTP)  | jupyter\_      |

## 2. Deployment Workflows

### 2.1 Deploying OpenClaw

OpenClaw is an autonomous agent ecosystem tailored for Indian developers. The EasyDeploy flow automates the provisioning of the orchestrator and reasoning engine.<br>

Steps for Deployment:<br>

1. Infrastructure Setup: Before launching, ensure you have created the required networking dependencies:
2. VPC & Subnet: Select your preferred Virtual Private Cloud and specific subnet.
3. Network & Security Group (SG): Ensure your Security Group allows inbound traffic on port 443 for web access.
4. API Integration: You must provide or create a Model API Key (e.g., from Krutrim AI Studio) to serve as the agent's reasoning "brain".
5. Provisioning: Navigate to the EasyDeploy tab in the Krutrim Console, select "OpenClaw," and click Deploy.
6. Verification: Once the status changes from "Provisioning" to "Running," the VM will appear in your "My Instances" list with the prefix openclaw\_ (e.g., openclaw\_assistant\_01).
7. Access: You can access the OpenClaw Web UI directly via the public IP:
8. URL Format: https\://\<VM\_IP>/

Pricing: Pricing for this feature is the same as standard VM pricing for the selected flavor, with no additional charges.

Disclaimer: The data you expose using OpenClaw is strictly your responsibility. Krutrim is not responsible for any data exposure, as OpenClaw is an open-source software. Please refer to the [OpenClaw GitHub repository](https://github.com/openclaw-rocks/openclaw-operator) for the source code and official documentation.<br>

### 2.2 Deploying Jupyter Notebook

The Jupyter Notebook template provides a sandboxed environment with pre-installed Python libraries and ML tools.

Steps for Deployment:

1. Infrastructure Setup: Configure the foundational networking components:
2. VPC & Subnet: Identify the region and network for deployment.
3. Security Group: Open port 8888 in your Security Group configuration to allow browser access to the Jupyter server.
4. Provisioning: Select the Jupyter Notebook template from the EasyDeploy menu.
5. Verification: Monitor the deployment progress in the dashboard. The VM will be created with the prefix jupyter\_ (e.g., jupyter\_research\_env).
6. Access: Access your notebook environment using the following URL:
7. URL Format: http\://\<VM\_IP>:8888

## 3. Post-Deployment Management

All instances created via EasyDeploy will appear in the "My Instances" page with their respective prefixes. From there, you can perform the following lifecycle operations through the Krutrim Console:<br>

* View: Track status and resource utilization.
* Start/Stop: Manage costs by pausing instances when not in use.
* Delete: Remove instances and associated block storage when no longer required.<br>

## 4. Troubleshooting & Best Practices

* Networking: If the VM is "Running" but the URL is inaccessible, verify that your Security Group explicitly allows ingress on the required ports (443 for OpenClaw, 8888 for Jupyter).
* API Keys: For OpenClaw, ensure your API key has sufficient token limits to avoid inference failures.
* Identification: Always check for the openclaw\_ or jupyter\_ prefix in the instance list to distinguish EasyDeploy VMs from standard compute instances.

<br>


# AI Pods

Ola Krutrim offers a state-of-the-art container service designed to meet the diverse computational needs of developers, researchers, and enterprises. Our platform provides a range of high-performance machine configurations, enabling users to select the optimal setup for their specific projects, whether for training complex machine learning models, running intensive simulations, or handling other GPU-accelerated tasks. AI Pod is more suitable for deploying a service, e.g., an inference endpoint. It is also suitable for development due to its Jupyter Notebook feature.

A Pod includes several components: a container volume that houses the operating system and temporary storage, a disk volume designated for permanent storage, an Ubuntu Linux container, assigned vCPU and system RAM, GPUs for specialized tasks, a pre-configured template to simplify software access, an SSH connection, and a proxy connection to enable web access.

Each Pod encompasses a variety of components:

* A container disk that houses the operating system and temporary storage.\
  This storage is volatile and will be lost if the Pod is stopped.
* A volume disk for permanent storage, associated with the pod as long as it is not terminated.\
  This storage is persistent and will be available even if the Pod is stopped.\
  But if the pod is terminated, the volume disk will be terminated, and the content in the disk will be deleted.
* An Ubuntu Linux container capable of running almost any software that can be executed on Ubuntu. We will add other OS flavors in the future. Please reach out to <sales@olakrutrim.com> if you want to request a new OS flavor.
* Assigned vCPU and system RAM dedicated to the container and any processes it runs.
* GPUs, tailored for specific workloads like CUDA or AI/ML tasks.
* A pre-configured template that automates the installation of software and settings upon Pod creation, offering straightforward, one-click access to various packages.

***

### Setting up a Pod

You need to select the right configuration of Pods available based on your requirements. You should focus on three items specifically, depending on the use case:

* GPU
* VRAM
* Disk Size

We also support spliced GPUs. You can use it for use cases that don’t require a full GPU.

You can use the help of the tools below to understand Pod requirements:

* [Hugging Face’s Model Memory Usage Calculator](https://huggingface.co/spaces/hf-accelerate/model-memory-usage)
* [Vokturz’ Can it run LLM calculator](https://huggingface.co/spaces/Vokturz/can-it-run-llm)
* [Alexander Smirnov’s VRAM Estimator](https://vram.asmirnov.xyz/)

Once you have a clear understanding of the pod configurations required, follow the steps below:

1. Choose the configuration of the Pod you want to use.
2. Please select the template you want installed in the pod specific to your use case. If you want any more templates installed from our side, please reach out to us at <sales@olakrutrim.com>
3. Please add your SSH key. You can refer to this document on how to generate an SSH key. Please select the checkbox for SSH terminal access if you want to access the Pods through the terminal.
4. Please select the checkbox for Jupyter Notebook if you want to run your code on Jupyter Notebook
5. Please add the respective volume mount path to which you want to connect the volumes.
6. Please select the Container Disk (Temporary) and Volume Disk (Persistent). Please note that you will be billed for the storage you selected and not for how much storage you used.
7. Once all details are filled in, you can click on Deploy to deploy the pod.
8. Once the pod is deployed, you can see the “Running” status on your pod.

{% hint style="warning" %}
Currently, we don’t support editing a Pod once it’s deployed. Once a pod is deployed with the container disk and volume disk selected, you can’t add more.
{% endhint %}

***

### Connecting to a Pod

Follow the steps below to connect to a pod:

1. Click on the three dots to the right of your pod
2. Click on **Connect**
3. You can use two ways to connect to the pod:
   * By clicking on the “Open” button near the **Jupyter Notebook**. This will open the Jupyter Notebook in a new tab, and you can run your code in there
   * Copy and paste the command mentioned in the **SSH terminal** in your terminal and run it in your system terminal. This will connect your terminal to the pod

***

### Stopping and terminating a Pod

You can click on the **Stop** button to stop your Pod.

* Please note that you **won’t be charged** for the Pod or container disk once your pod is stopped, but you **will be charged** for the Volume disk till the pod is terminated.
* You will also **lose all the data in the container disk** once the pod is stopped.
* Your Volume disk will remain intact, as well as the data in the Volume disk. You can access the data once you restart the pod.

You can click on the **Terminate** button to terminate your pod.

* Once you terminate the pod, you **won’t be charged** for the pod, or the container disk, or the volume disk.
* You will **lose access to both the container disk and the volume disk**. You will lose the data as well.

<br>


# Machine Images

Machine Images allow users to upload and manage custom virtual machine images, which can later be used to launch VMs with pre-installed configurations and software. This service is useful for users who want reusable environments or want to migrate their VM setup.

***

### Uploading a Machine Image

Clicking **Upload Machine Image** opens a new page to configure and upload a custom image.

#### Required Fields:

| Field                    | Description                                                            |
| ------------------------ | ---------------------------------------------------------------------- |
| **Image Type**\*         | Selectable from a dropdown. Currently we support QCOW2 and RAW formats |
| **Machine Image Link**\* | The object storage link to the machine image                           |

#### Restrictions:

* **Max File Size:** 1024 GB
* **MIME Inspection:** Uploaded files will go through **Magic Byte (MIME type) validation**. This ensures the file is a valid and secure machine image, even if the extension appears valid. Files that fail this validation will be rejected.

**Uploading a machine image to the Krutrim Object storage bucket**

* Create an Object storage bucket using the steps mentioned [here](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/storage/object-storage#creating-a-bucket)
* Once you have created the bucket, upload your image file to the bucket
* Once the file is uploaded, click on the three dots
* Click on the "three dots" near your image uploaded and click on the "Copy Presigned URL" button
* Copy and paste the URL to the Machine image link text field and click on upload

***

### Deleting a Machine Image

Each image has an **Actions** menu with an option to **Delete**.

Clicking **Delete** will open a confirmation pop-up:

> **Header:** Are you sure you want to delete the Machine Image?\
> **CTAs:**
>
> * Cancel
> * Confirm Deletion

Once confirmed, the image will be permanently deleted and cannot be used to create VMs.

***

### Downloading a Machine Image

Each image in the table also includes a **Download Machine Image** option in the **Actions** menu.

Clicking this will immediately begin downloading the machine image to your local system.


# SSH Key

SSH keys are a secure way to authenticate with servers and services without using passwords. Follow these steps to generate your SSH key pair and use your public key.

***

### For MacOS and Linux Users

#### 1. Open Terminal

You can find Terminal in Applications > Utilities or by searching for it using Spotlight (Cmd + Space and type "Terminal").

#### 2. Generate SSH Key Pair:

In the Term In the Terminal window, type the following command and press Enter:&#x20;

```
ssh-keygen
```

> This command generates a new SSH key using the RSA algorithm with 4096 bits.

#### 3. Follow the prompts

* Enter file in which to save the key: Press Enter to accept the default file location ``(`/Users/your_username/.ssh/id_rsa`)``.
* Enter passphrase: Type a secure passphrase for additional security (optional, but recommended).
* Enter the same passphrase again: Re-type your passphrase.

#### 4. Verify the keys :

To check if your keys were generated successfully, type:

```
ls ~/.ssh
```

* You should see \```id_rsa` (your private key)`` and \```id_rsa.pub` (your public key)`` in the list
* Copy the SSH Public Key
* To copy the SSH public key to your clipboard, type:

```
pbcopy < ~/.ssh/id_rsa.pub
```

***

### For Windows Users

#### 1. Open Terminal

You can use PowerShell or Windows Terminal.\
To open it, press Win + S, type PowerShell or Windows Terminal, and press Enter.

#### 2. Generate SSH Key Pair

In the Terminal window, type the following command and press Enter:

```
ssh-keygen -t rsa -b 4096
```

> This command generates a new SSH key using the RSA algorithm with 4096 bits.

#### 3. Follow the Prompts

* Enter file in which to save the key (e.g., `C:\Users\your_username\.ssh\id_rsa`):
* Press Enter to accept the default file location.
* Enter passphrase (empty for no passphrase):
* Type a secure passphrase for additional security (optional, but recommended).
* Enter the same passphrase again: Re-type your passphrase to confirm.

#### 4. Verify the Keys

To check if your keys were generated successfully, type:

```
Get-ChildItem $env:USERPROFILE\'.ssh\'
```

You should see two files in the list: id\_rsa (your private key) and id\_rsa.pub (your public key).

#### 5. Copy the SSH Public Key

To copy the SSH public key to your clipboard, type:

```
Get-Content $env:USERPROFILE\.ssh\id_rsa.pub | Set-Clipboard
```

<br>


# Billing for Compute

Krutrim Cloud offers transparent and usage-based pricing for all compute services, including **VMs, AI Pods, and GPU Baremetals**. This guide will help you understand how billing is calculated and what to expect on your invoices when using our compute infrastructure.

***

### Billing Overview

Compute resources are billed **based on actual usage**, with rates displayed on an **hourly basis**. However, Krutrim applies **fine-grained metering**, ensuring you're only charged for what you use, in **15-minute billing intervals**.

{% hint style="warning" %}
You are only billed while your resources are in an **active** state (running or initialising). Stopped or terminated resources do not incur compute charges, although associated storage or IPs may continue to incur costs.
{% endhint %}

***

### Metering and Billing Logic

Even though prices are shown as per-hour rates, the actual metering happens in **15-minute increments**. The minimum billable unit is 15 minutes.

#### Example Billing Scenarios:

| Usage Duration    | Billed Duration      |
| ----------------- | -------------------- |
| 1 hour 40 minutes | 1 hour 45 minutes    |
| 2 hours 5 minutes | 2 hours 15 minutes   |
| 35 minutes        | 45 minutes           |
| 14 minutes        | 15 minutes (minimum) |

This granularity ensures that you are billed fairly and precisely, with charges rounded **up** to the nearest 15-minute mark.

{% hint style="info" %}
Taking the first case as an example, if a user uses an **A100-80GB-NVLINK-1x**, which is priced at **₹189/hour**, and the user runs the VM for **1 hour 40 minutes**, the billed duration will be **1 hour 45 minutes**. Hence, the final bill will be **189 + 189 × (45/60) = ₹330.75**.
{% endhint %}

***

### Billing by Compute Type

#### Virtual Machines (VMs)

Please refer to our [Pricing page.](broken://pages/VJjxSml8oHCwP7uqIXxi)

***

#### GPU Baremetals

GPU Baremetal servers provide exclusive access to full GPUs for high-performance workloads. These are **custom-configured deployments** and require you to **contact our sales team** for pricing and provisioning.

To request GPU Baremetal pricing, please reach out to our Sales team at **<sales@olakrutrim.com>**

***

### Billing

Our Billing cycle happens every **15 minutes**, but you will be charged for the duration during which you used the pod during those 15 minutes.

**Example**:\
Let’s say you started a pod at 10:00 and you terminated the pod at 10:10.\
➡️ You will only be charged for **10 minutes**.

### Other Considerations

* **Attached Storage**: Any block storage volumes attached to compute instances will be billed separately based on the size and duration of attachment.
* **Elastic IPs**: IPs assigned to stopped or unattached VMs may incur additional costs.
* **Snapshots and Backups**: Charged independently based on size and retention period.
* **Overage or Quota Breach**: Exceeding free-tier or reserved quota (if applicable) will automatically incur standard pricing.

***

### Where to View Usage

You can track your ongoing usage and estimated billing:

* In the **Billing Dashboard** on the Krutrim Console
* Via **API** or SDK for programmatic access to usage summaries
* Through **alerts and usage reports**, which can be configured by account or project


# Auto Scaling Groups

Auto Scaling Groups (ASGs) on Krutrim Cloud provide a managed way to automatically adjust virtual machine (VM) capacity in response to demand. ASGs help users maintain application performance while optimizing cost and operational efficiency by scaling resources up or down based on policy-driven triggers or scheduled actions.

ASGs can be created directly or derived from reusable templates, enabling users to standardize instance configurations and group behaviors across environments.

This document explains how ASGs function on Krutrim Cloud, how to configure and manage them, and how templates, policy configuration, dashboards, and UI behaviors work.

#### Key Concepts

**1) Auto Scaling Group**

An Auto Scaling Group is a logical construct that:

* Launches VMs based on instance configuration.
* Adjusts the number of running VMs automatically.
* Applies policies such as CPU usage, memory usage, or schedule-based triggers.
* Ensures defined minimum, desired, and maximum capacity boundaries.

ASGs are suitable for:

* Web servers and APIs with fluctuating load
* ML inference services
* Queue processing and worker pools
* Batch workloads with predictable schedules

2\) ASG Templates

#### Creating an Auto Scaling Group

**ASG Specification**

1. **Name :** A unique identifier for the ASG within the selected VPC.
2. **Creation Mode:**
   1. From Scratch: All fields start empty.
   2. From Template: Selecting a template pre-populates values. All values remain editable.
3. **Region**
   1. Auto-filled from the global region selector.
   2. User can override via dropdown.
4. **VPC:** Only VPCs in the selected region are shown. Dynamically updated if the region changes.
5. **Subnet:**
   1. Single-select from subnets within the chosen VPC.
   2. Subnets are shown with CIDR and public/private tag.
6. **Security Groups:**
   1. Multi-select.
   2. Lists all security groups associated with the selected VPC.

***

**Instance Configuration**

1. **Instance Name:** Base name used as prefix for VMs launched by this ASG.
2. **Instance Type:** CPU instance types with displayed specifications and per-hour pricing.
3. **Scaling Configuration:**
   1. Minimum capacity
   2. Maximum capacity
   3. Validation:
      1. `min ≤ max`
4. **Bootable Volume:**
   1. Configured with:
      1. Size
      2. Name
      3. Machine image
5. **Additional Storage Volume:**
   1. Users may attach multiple volumes.
   2. All such volumes are **ephemeral** and deleted when the instance terminates.
6. **SSH Key:**
   1. Used for secure access to VMs created by the ASG.

***

**Scaling Policies**

An ASG may include **one of each** of the following policies:

1. **Average CPU Utilization**
2. **Average Memory Utilization**
3. **Scheduled Scaling Action**

All policies are additive but only one policy of each type is allowed.

***

**CPU / Memory Utilization Policies**

Each policy includes:

* **Upscale Target (%):**\
  VM count increases when aggregated usage exceeds this threshold.
* **Downscale Target (%):**\
  VM count decreases when usage falls below this threshold.
* **Scale-out Cooldown:**\
  Prevents immediate re-execution of scale-out logic.
* **Scale-in Cooldown:**\
  Prevents immediate re-execution of scale-in logic.

**Validation rules:**

* Upscale and downscale values may be equal (allowed with warning).
* Downscale target may not exceed upscale target.

***

**Scheduled Actions**

Scheduled policies allow users to define:

* A **scale-up time**
* A **scale-down time**

Both times cannot be identical

***

**Saving as Template**

At the end of the creation process, users may enable:

**Save as Template**

* Creates a template with name **`<ASG Name> Template`**
* Captures full configuration (instance + ASG + policies)
* Template becomes available for future ASG creation.


# Functions

## Introduction

Function-as-a-Service (FaaS) is a serverless compute model that lets you run code in response to events, without managing servers, containers, or runtime environments. With Krutrim Cloud FaaS, you can deploy small units of code called functions, and the platform automatically handles infrastructure provisioning, scaling, availability, and runtime updates. Functions execute only when triggered (such as by HTTP requests) and stop when the work is complete.&#x20;

With Krutrim Cloud Functions you can remove operational complexity and accelerate development. Functions scale automatically based on demand, including scaling to zero when idle, and users pay only for actual execution rather than idle capacity. Built-in logging, metrics, and fault isolation improve reliability and observability.

## Configurations

We currently offer 3 runtimes - Python, Node.js, Go

The configurations we offer are based on the **maximum** memory allocated to the function. Compute and storage are allocated in proportion to the amount of memory configured.&#x20;

{% hint style="info" %}
To increase the memory, CPU power and storage allocated to your function, select a higher memory configuration.
{% endhint %}

| Configuration    | Memory  | Use case                       |
| ---------------- | ------- | ------------------------------ |
| S (small)        | 256 MB  | Basic APIs, lightweight tasks. |
| M (medium)       | 512 MB  | Standard workloads.            |
| L (large)        | 1024 MB | Data processing, ML inference. |
| XL (extra large) | 2048 MB | Heavy computation.             |
| 2XL              | 4096 MB | Large-scale processing.        |

## Billing

Functions are billed in **GB-seconds**.

**GB-seconds = Allocated Memory (GB) × Total pod active duration (seconds)**

Each function is charged at **₹0.001 per GB-second**.

**How billing works**

* Functions automatically scale between **1 to 10 pods** based on incoming traffic.
* Pods may remain running for a short duration after request completion to handle potential additional traffic.
* Billing is calculated based on the **total time the function pods remain active**, including any idle time before they scale down.
* You are **not billed per request**, but for the overall active runtime of the function infrastructure.

**Example**

If:

* Memory allocated = 1 GB
* A request executes in 2 seconds
* The pods remained active for a total of 8 seconds before scaling down

Total usage = 1 GB × 8 seconds = 8 GB-seconds\
Total cost = 8 × ₹0.001 = ₹0.008

## Create Function

1. Go to 'Core Infrastructure > Compute > Functions' and click on the 'Create Function' button.
2. Select the desired runtime for your function and add a function name.
3. Select the memory configuration depending on your function size and needs.
4. Add the timeout value for the function (default is set to 60 seconds). Timeout is the maximum duration a function is allowed to run. A shorter value will enable quick error detection and prevent resource leaks. Longer values are typically used to support ML and compute-heavy workloads.
5. Add your code in the code editor. Click on the template button to add sample code to get you started.&#x20;
6. You can add environment variables in the 'Function Configuration' tab.
7. Once you are satisfied with your function's code and settings, click on 'Create'. You can run the function to see outputs, after deployment.&#x20;
8. To test and manage your function, click on 'Manage' from the actions menu.

## Manage Function

1. You can modify your existing code from the 'Code' tab. Click on 'Save' to save your code, before building. Click on 'Build' to build your code and view build logs. Click on 'Deploy' to deploy your changes after a successful build.
2. You can test your function on the 'Test' tab. The code here cannot be modified. In order to modify your existing code, use the 'Code' tab.&#x20;
3. Click on the 'Add test event' button, to add an event JSON. Click on 'Test' to run your function with the test event inputs.&#x20;
4. You can view your function's metrics and performance on the 'Monitor' page. They provide you with information such as duration of execution, number of invocations, error count etc. You can also view the build logs and runtime logs on this tab.
5. You can edit your function's settings on the 'Function Configuration' tab. You can change the memory configuration, timeout value, and environment variables.&#x20;


# Storage

Krutrim Cloud provides scalable, persistent, and cost-effective storage options to meet a wide range of infrastructure and AI workload needs. From object storage for unstructured data to block volumes for high-performance compute instances, Krutrim’s storage offerings are built for flexibility, durability, and ease of use.

### Available Storage Services

<table><thead><tr><th width="192.23046875">Service</th><th>Description</th></tr></thead><tbody><tr><td><strong>Object Storage</strong></td><td>Highly durable storage for unstructured data like datasets, logs, media files</td></tr><tr><td><strong>Block Storage</strong></td><td>High-performance volumes for attaching to VMs, AI Pods, and Baremetals</td></tr><tr><td><strong>Snapshots</strong></td><td>Point-in-time backups of block volumes for recovery and cloning</td></tr><tr><td><strong>Backups</strong></td><td>Long-term, durable backups of volumes with cost-effective storage pricing</td></tr><tr><td><strong>Policies</strong></td><td>Custom lifecycle policies for automated snapshot and backup management</td></tr></tbody></table>


# Block Storage

Krutrim cloud offers three main Block storage services mentioned below;

1. Volumes
2. Snapshots
3. Backups

### [Pricing](/basics/pricing/storage) <a href="#pricing" id="pricing"></a>


# Volumes

### What is a Volume? <a href="#what-is-a-volume" id="what-is-a-volume"></a>

A **Volume** is a virtual block device that provides persistent storage for your virtual machines. You can read from and write to it just like a physical disk. Krutrim Volumes are built on high-speed NVMe SSDs, offering low latency and high IOPS for demanding workloads. Volumes can be created independently and attached to a VM at a time.

One volume can be attached to one VM at a time.

Our volumes offer one of the highest performances in the world, with **4000 MBPS read/write speed and 64000 IOPS throughput**.

Our volumes are priced at **Rs 7.88 per GB Per Month.**

***

### Creating a Volume <a href="#creating-a-volume" id="creating-a-volume"></a>

1. Navigate to **Block Storage → Volumes**.
2. Click **Create Volume**.
3. Provide:
   * **Volume Name** (required)
   * **Description**
   * **VPC** (select from list or create new)
     * Please note that you select the respective VPC in which your VM, to which you want to attach, is present. You won’t be able to attach the volume to a VM present in a different VPC.
   * **Volume Type**: `High-speed NVMe SSD`
   * **Source**: `None`, `Snapshot`, `Machine Image`, `Other Volume`
     * You can create a volume from any one of the options
       * None - Select this option if you want to create an empty volume
       * Snapshot - Select this option and the respective snapshot in the next option if you want to create your volume from a snapshot
       * Machine Image - Select this option and the respective Machine Image in the next option if you want to create your volume from a Machine Image
       * Other Volume - Select this option and the respective volume in the next option if you want to create your volume from an existing volume. This is similar to copying from one volume to a new volume
     * Please note that based on the source, your created volume will become either a bootable volume or a storage volume
   * **Size**: Between 4 GB to 2048 GB
     * Currently, we support up to a maximum of 2048 GB. If you require more, please reach out to <cloudsupport@olakrutrim.com>
   * **Tags** (optional)
     * Tags are another way to group your resources
   * **Advanced Settings** (optional):
     * Assign **Snapshot Policy**
       * Create a snapshot policy during the creation of the volume to automatically create snapshots
     * Assign **Backup Policy**
       * Create a Backup policy during the creation of the volume to automatically create backups
4. Click **Create**. Volume will be provisioned and status updated.

***

### Extending a Volume <a href="#extending-a-volume" id="extending-a-volume"></a>

* Volumes can be **grown** (resized to a larger size), but not shrunk.
* Extension happens live if the volume is not in use, or after a reboot if it is attached. You won’t have to detach the volume from a VM to extend the size. The extension will be done immediately.

Steps:

1. Click the three-dot menu → **Extend Volume**.
2. Enter a **larger size**.
3. Confirm the operation.

***

### Editing a Volume <a href="#editing-a-volume" id="editing-a-volume"></a>

* You can update:
  * **Description**
  * **Tags**
  * **Associated Snapshot/Backup Policies**

Navigate to the volume → **Edit**.

***

### Deleting a Volume <a href="#deleting-a-volume" id="deleting-a-volume"></a>

1. From **Volumes**, click the three-dot menu → **Delete Volume**.
2. You must **detach** it from any VM before deletion.
3. Confirm to permanently delete.

***

### **Creating an Instant Snapshot**

This action creates an instant point-in-time snapshot for your volume

1. Click on the three dots
2. Click on "Create Instant Snapshot"
3. Enter the snapshot name
4. Add other details like description or tags if needed
5. Click on "Create snapshot"
6. This will create your instant snapshot

***

### **Creating an Instant Backup**

This action creates an instant point-in-time snapshot for your volume

1. Click on the three dots
2. Click on "Create Instant Backup"
3. Enter the backup name
4. Add other details like description or tags if needed
5. Click on "Create backup"
6. This will create your instant backup


# Snapshots

### What is a Snapshot? <a href="#what-is-a-snapshot" id="what-is-a-snapshot"></a>

A **Snapshot** is a point-in-time copy of a volume. Snapshots capture the current state of your data and are ideal for short-term backups, testing, or versioning. They can be used to restore the VM to a previous state or to create new volumes.

* Snapshots are stored in the same zone.
* Snapshots can be created:
  * **Manually**
  * **Automatically via Snapshot Policies**

***

### Creating a Snapshot (Manual or Policy) <a href="#creating-a-snapshot-manual-or-policy" id="creating-a-snapshot-manual-or-policy"></a>

**Manual Snapshot:**

1. Go to **Volumes** → three-dot menu → **Create Instant Snapshot**.
2. Enter:
   * **Name**
   * **Description**
   * **Tags**
3. Click **Create**.

Or

1. Go to snapshots
2. Click on “Create Instant Snapshots”
3. Select the volume or VM for which you want to create a snapshot
4. Enter:
   * **Name**
   * **Description**
   * **Tags**
5. Click **Create**.

**Policy-Based Snapshot:**

* You can create policy-based snapshots in two ways:

Approach 1:

* Go to snapshots
* Click on "Create Snapshot policies"
* Select either a VM snapshot to create a snapshot for a VM or a Volume snapshot for a volume
* Select the VM or volume
* Select the maximum number of snapshots that you want to create for the respective volume or VM
* Enter the policy name
* Enter the description
* Select appropriate values for the scheduler
* Click on "Create Policy"
* This will create a snapshot for the scheduler you have created

Approach 2:

* While you create your volume, you can add the snapshot policies, which will create a snapshot for the volume

***

### Snapshot Creation Logic <a href="#snapshot-creation-logic" id="snapshot-creation-logic"></a>

* The first snapshot created will be the **Primary (#1)**
* Additional snapshots: `#2`, `#3`, ..., up to the maximum limit.
* When the retention limit is hit:
  * The oldest primary is rotated out.
  * Newest becomes `#1`.

Currently, we don’t support incremental snapshots.

When you create a volume or a VM from a snapshot, since the snapshot is an instant snapshot, it will create the volume/VM from whatever existed in the volume when the snapshot was created

***

### Deleting a Snapshot <a href="#deleting-a-snapshot" id="deleting-a-snapshot"></a>

1. Navigate to **Snapshots**.
2. Click on the three dots
3. Click **Delete**.

***

### Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

Our snapshots are priced at **Rs 4.38 per GB Per Month**, one of the cheapest prices in the world.

Even though it’s priced at a Monthly rate, the billing happens every hour at a rate of Rs 0.006 per GB per hour. You will be charged for the total peak storage, for all the snapshots you have used in the hour. For example, if you have used 100 GB across all your snapshots during the hour, you will be charged 100\*0.006 = Rs 0.6.

<br>


# Backups

### What is a Backup? <a href="#what-is-a-backup" id="what-is-a-backup"></a>

A **Backup** is a durable, zone-resilient copy of a volume, optimized for disaster recovery. Unlike snapshots (which are stored locally), backups are replicated across availability zones or regions and are designed for long-term retention and restoration of your data.

Our backups are priced at **Rs 1.83 per GB Per Month.**

* Backup storage can be incremental or instant.
* Use backups to recover from accidental deletion, failures, or corruption.
* Can be created:
  * **Manually**
  * **Automatically via Backup Policies**

***

### Creating a Backup (Manual or Policy) <a href="#creating-a-backup-manual-or-policy" id="creating-a-backup-manual-or-policy"></a>

**Manual Backup:**

1. Go to **Volumes** → three-dot menu → **Create Instant Backup**.
2. Enter:
   * **Name**
   * **Description**
   * **Tags**
3. Click **Create**.

Or

1. Go to Backup
2. Click on “Create Instant Backup”
3. Select the volume or VM for which you want to create a Backup
4. Enter:
   * **Name**
   * **Description**
   * **Tags**
5. Click **Create**.

**Policy-Based Backup:**

* You can create policy-based backup in two ways;
* Approach 1;
  * Go to Backup
  * Click on "Create Backup policies"
  * Select either a VM Backup to create a backup for a VM or a Volume Backup for a volume
  * Select the VM or volume
  * Select the maximum number of backups that you want to create for the respective volume or VM
  * Enter the policy name
  * Enter the description
  * Select appropriate values for the scheduler
  * Click on "Create Policy"
  * This will create a Backup for the scheduler you have created
* Approach 2;
  * While you create your volume, you can add the backup policies, which will create a backup for the volume

***

### Backup Creation Logic <a href="#backup-creation-logic" id="backup-creation-logic"></a>

* The first backup or any instant backups = **Primary (#1)**.
* Additional backups follow: `#2`, `#3`, ..., up to policy-defined limit for both Instant and Incremental backups
* In case of Incremental backups `#2`, `#3` will become Delta backups.
* When the limit is hit:
  * The oldest non-primary backup is overwritten in case of Incremental backups, and the oldest backup will be overwritten in case of non-incremental backups
  * \#2 will become the newest backup in case of Incremental backups, and #1 will become the newest backup in case of non-incremental backups.

***

### Restoring a Backup <a href="#restoring-a-backup" id="restoring-a-backup"></a>

1. Go to **Backups**.
2. Click on the three dots
3. Click **Restore Backup**.
4. A **new volume** will be created:
   * With the primary + delta changes
   * Restored to the exact point in time

***

### Deleting a Backup <a href="#deleting-a-backup" id="deleting-a-backup"></a>

1. Navigate to **Backups**.
2. Click **Delete**.
3. Primary backup cannot be deleted unless a new one is marked as Primary.

***

### Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

Our volumes are priced at **Rs 1.83 per GB Per Month**, one of the cheapest prices in the world.

Even though it’s priced at a Monthly rate, the billing happens every hour at a rate of Rs 0.003 per GB per hour. You will be charged for the total storage you have used in the hour across all your backups. For example, if you have used 100 GB across all your backups during the hour, you will be charged 100\*0.003 = Rs 0.30.

<br>


# Object Storage

### What is Object Storage?

Object Storage on Krutrim Cloud is designed for storing and managing large-scale unstructured data such as logs, images, videos, backups, or static assets. It is built to provide durability, scalability, and ease of access via APIs or a web interface.

### Use Cases

* Hosting static websites and assets
* Backup and archival storage
* Storing logs, data exports, and training datasets
* Mobile or web app storage backend
* Media hosting (images, videos, documents)

We currently support only 1 variant of object storage: Standard Frequent access with Read speed of **1711.63 MiB/s**, Average **TTFB 17 m**s, and write speed **570.35 MiB/s**.\
\
It is S3-compatible, meaning you can use popular tools like s3cmd and boto3 to interact with your data.

### Creating a bucket

1. You can create a bucket by clicking on the "Create Bucket" option in the Object Storage Page
2. Please enter the details below
   1. Bucket name - Please follow the bucket naming rules
   2. Region - Please make sure you select the region closest to your location for faster access to the objects
   3. Access Control;
      1. Public - For publicly accessible files
      2. Private - For files to be accessed by only specific IPs
   4. Bucket Versioning - Enable it to support versioning
   5. Default Encryption - Always enabled
   6. Tags - Enable them to clearly identify your buckets
3. Click on Create bucket, and your bucket will be created

### Accessing Buckets

The objects are encrypted at a bucket level and at the hardware level. To access the objects, you will need a secure session.\
&#x20;

1. If you already have an Access Key and Secret Key, please enter them
2. If you don't have them, you can click on the "Create API Keys" to create a new key.
3. Please note to save the secret key, as once you create it, you won't be able to see it again

**Uploading objects**

Once you have accessed the bucket, you can click on the upload file button and select the files you want to upload. This will upload the files

**Moving Objects**

You can move your objects between folders in the same bucket by clicking on the "Move Object" button in the actions and selecting the desired folder

### Bucket Policies

You can create a bucket policy to decide which IP addresses can read or write into your buckets

1. Once you are inside the bucket, click on policies
2. Mention all the IP addresses you want to read from your bucket and write to your bucket by commas in the Read-Write IPs box
3. Mention all the IP addresses you want to read from your bucket, only by commas in the Read-Only IPs box
4. Click on Create policy, and your policy will be created

### CLI Commands

**Configure Your S3-Compatible Tool**

1\. Copy Endpoint URL: In the console, navigate to your bucket, click on "Actions", and copy the endpoint URL.\
2\. Configure Tool:<br>

* Use your `access_key`, `secret_key`, and the copied endpoint to configure your S3-compatible tool.
* For `s3cmd`, run: `s3cmd --configure`
* Enter your keys and the endpoint URL when prompted.
* For `boto3`, Add the keys and endpoint URL to your AWS configuration files.

#### Manage Objects Using S3-Compatible Tool (`s3cmd`)

Now that your tool is configured, you can start uploading, downloading, and managing your objects.

**Upload an Object:**

```
s3cmd put /path/to/file s3://your-bucket-name/your-object-name
```

**Download an Object:**

```
s3cmd get s3://your-bucket-name/your-object-name /path/to/destination
```

**Delete an Object:**

```
s3cmd del s3://your-bucket-name/your-object-name
```

**List Objects in a Bucket:**

```
s3cmd ls s3://your-bucket-name
```

### API References

You can find the API References [here](https://krutrim-cloud-documentation.gitbook.io/krutrim-cloud-documentation/~/revisions/mnaZK7Kdd0lEYe2ga4yn/api-references/object-storage-api)


# Billing for Storage

Krutrim Cloud provides flexible, usage-based pricing for all storage services including **Block Storage**, **Snapshots**, **Backups**, and **Object Storage**. This guide outlines the pricing models, metering logic, and example calculations to help you understand and manage your storage costs effectively.

***

### Billing Overview

Storage usage is metered **hourly**, and prices are displayed on a **per GB per month** basis for ease of comparison. However, final billing is calculated on an **hourly peak usage** basis, which ensures you're charged accurately and proportionately.

You are only billed for **active storage** — i.e. attached block volumes, retained snapshots or backups, and stored objects.

***

### Block Storage

Block Storage volumes are persistent disks that can be attached to VMs or AI Pods. You can provision volumes ranging from **4 GB to 2048 GB**.

#### Pricing

* **Monthly Rate**: ₹7.88 per GB
* **Hourly Rate**: ₹0.011 per GB
* **Size Range**: 4 GB to 2048 GB

{% hint style="info" %}
*Need more than 2048 GB?*

Contact our sales team at <cloudsupport@olakrutrim.com> for custom provisioning.
{% endhint %}

***

### Metering Logic

All storage services follow a **peak usage metering model**, where:

* Usage is calculated based on **maximum provisioned or consumed capacity** in any given hour.
* The total monthly bill is the **sum of hourly peak usage**, multiplied by the hourly rate.

#### Example

{% tabs %}
{% tab title="Case 1" %}
**Single Volume, Consistent Size**

* Volume: 1 volume of 100 GB
* Duration: 10 continuous hours
* **Billing Calculation**: `100 GB × ₹0.011 × 10 hours = ₹11`
  {% endtab %}

{% tab title="Case 2" %}
**Multiple Volumes, Consistent Size**

* Volume 1: 50 GB for 10 hours
* Volume 2: 40 GB for 10 hours
* **Peak Hourly Usage**: 50 + 40 = 90 GB for each hour
* **Billing Calculation:** 90 GB × ₹0.011 × 10 hours = **₹9.90**
  {% endtab %}

{% tab title="Case 3" %}
**Dynamic Usage Across Volumes**

* Volume 1:
  * 50 GB for first 5 hours
  * 40 GB for next 5 hours
* Volume 2: 20 GB for entire 10 hours

| Time Period | Volume 1 (GB) | Volume 2 (GB) | Total Peak (GB) |
| ----------- | ------------- | ------------- | --------------- |
| Hours 1–5   | 50            | 20            | 70              |
| Hours 6–10  | 40            | 20            | 60              |

* **Billing Calculation**:\
  `(70 GB × ₹0.0068 × 5 hours) + (60 GB × ₹0.0068 × 5 hours)`\
  `= ₹2.38 + ₹2.04 = ₹4.42`
  {% endtab %}
  {% endtabs %}

***

### Snapshots

Snapshots are point-in-time backups of your block volumes. You can use them to restore or clone volumes.

***

### Backups

Backups are long-term, durable storage copies of your volumes and can be stored independently of the source.

{% hint style="info" %}
Backups are billed separately from volumes and snapshots, even if they contain the same data.
{% endhint %}

***

### Object Storage

Krutrim Cloud Object Storage offers scalable, highly available storage for unstructured data such as backups, images, videos, and application data.&#x20;

### **Pricing Structure**

| Storage Type / Tier | Flavor         | Unit | Price / GB / Hour | Price / GB / Month |
| ------------------- | -------------- | ---- | ----------------- | ------------------ |
| Tier 1              | 0 – 5 GB       | Hour | ₹0                | ₹0                 |
| Tier 2              | 5 GB – 50 TB   | Hour | ₹0.0023           | ₹1.66              |
| Tier 3              | 50 TB – 500 TB | Hour | ₹0.0022           | ₹1.61              |
| Tier 4              | Above 500 TB   | Hour | ₹0.0021           | ₹1.54              |

***

### **Billing Details**

* **Metering**: Usage is metered hourly by using the peak storage of that hour.
* **Free Tier**: First **5 GB** of storage per month is free.
* **Tiered Billing**: Pricing is applied per tier based on total monthly usage. For example:
  * If you store **60 TB** in a month:
    * First 5 GB → Free
    * Next 49.995 TB → ₹1.66/GB
    * Remaining 10 TB → ₹1.61/GB
* **Pro-Rata Charges**: If storage is created or deleted during the month, charges apply only for the hours used.
* **Minimum Billing Interval**: 1 hour.

***

### **Example Cost Calculation**

**Scenario**:\
A customer stores **120 TB** of data for a full month.

**Calculation**:

* Tier 1: First 5 GB → ₹0.00
* Tier 2: Next 49.995 TB → 49,995 GB × ₹1.66 = ₹82,992.70
* Tier 3: Next 70 TB → 70,000 GB × ₹1.61 = ₹112,700.00\
  **Total = ₹195,692.70 for the month**

***

### Additional Billing Considerations

* **Detached Volumes**: You will still be charged for storage even if a volume is detached from a VM.
* **Retained Snapshots or Backups**: These incur ongoing costs as long as they are stored in your account.
* **Data Transfer Costs**: Intra-region data movement is free, but egress or inter-region transfers may incur charges (coming soon).


# Networking

Krutrim Cloud's networking stack is designed to give users fine-grained control over how their resources communicate within and outside the cloud. It provides secure, scalable, and configurable building blocks to design modern cloud-native network architectures.

In this section, you'll learn how to configure and manage the following core networking components:

* **Virtual Private Cloud (VPC):**\
  A logically isolated virtual network where you launch and manage your compute and storage resources. You can define custom IP ranges, routing rules, and access boundaries.
* **Subnets:**\
  Sub-segments within a VPC used to logically separate resources (e.g., public-facing vs internal workloads). Each subnet resides within a specific availability zone and supports granular control over traffic flow.
* **Security Groups:**\
  Virtual firewalls that control inbound and outbound traffic to your instances. These operate at the instance level and support rule-based filtering by protocol, port, and source/destination IP.
* **Static IPs:**\
  Public, routable IP addresses that can be allocated to and reassigned across VMs or services. These are ideal for services requiring consistent external endpoints (e.g., web servers, APIs).

Krutrim Cloud ensures that all these components integrate seamlessly to help you build secure, performant, and resilient applications. Whether you're setting up a simple VM or deploying a complex multi-tier architecture, this section will guide you through the required networking configurations.


# VPC

A **Virtual Private Cloud (VPC)** is a logically isolated network in a cloud environment where users can launch resources in a defined and controlled manner. It acts as the core network boundary for your resources, including compute, storage, and networking components, offering security and traffic control. The best analogy for a VPC is to consider if you are building a neighbourhood, where you will put all your resources (VM, Storage in this case), which is isolated from other neighbourhoods created by you or other resources, the neighbourhood here is the VPC

#### Key Properties <a href="#key-properties" id="key-properties"></a>

* VPCs are region-specific and cannot span multiple regions.
* Resources that require VPC attachment:
  * GPU VMs
  * CPU VMs
  * Block Storage
  * Subnets
  * Security Groups
  * Static IP Addresses
* Resources **excluded** from VPCs:
  * AI Pods
  * Object Storage (region-dependent, not VPC dependent)
  * AI Studio services
  * AI Solution services
  * Ola Maps services

***

#### Creating a VPC <a href="#creating-a-vpc" id="creating-a-vpc"></a>

1. Go to the **"Networking > VPC"** tab
2. Click **"Create VPC."**
3. Fill in:
   * VPC Name (required)
   * Region (required)
   * Description (optional)
   * You can also configure your subnet configurations in the advanced settings like:
     * Subnet Name&#x20;
     * Subnet Description
     * CIDR
     * Gateway IP&#x20;
     * Network Accessibility
       * Public&#x20;
       * Private
4. Click **"Create VPC."**
5. New VPC will be listed with:
   * Name, Description, Region, Status and subnet settings

{% hint style="success" %}
You have the functionality to leave the subnet empty. We will create a default public subnet with the VPC
{% endhint %}

***

#### &#x20;Deleting a VPC  <a href="#deleting-a-vpc" id="deleting-a-vpc"></a>

Please note that you can delete your VPC only after all the attached resources with the VPC are deleted first.&#x20;

1. Click on the **three-dot menu** → **Delete VPC**
2. Two-step confirmation:
   * Enter VPC Name manually (no copy-paste)
3. If the input matches, the delete proceeds
4. If mismatch: Toast message shown and deletion cancelled

***

#### Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

| Service | Unit | Price / Hour | Price / Month |
| ------- | ---- | ------------ | ------------- |
| VPC     | Hour | ₹0.28        | ₹204          |

Our VPCs are priced at **Rs 0.28 per VPC per hour**.


# Subnets

A **Subnet** is a range of IP addresses within a VPC that groups resources. In the same analogy for VPC being the neighbourhood you have created for all your resources, isolated from other neighborhoods, Subnet here represents the particular segment/line/area inside your neighbourhood. You can determine if this area wants to be accessed by anyone publicly (Public subnet) or if it’s completely restricted to the people inside the area only (Private subnet)

* Can be **Public** (internet-facing) or **Private** (internal-only)
* One subnet can host multiple VMs

***

#### Creating a Subnet <a href="#creating-a-subnet" id="creating-a-subnet"></a>

1. Navigate to **Networking > Subnets**
2. Click **"Create Subnet"**
3. Fill in:
   * VPC (required)
   * Subnet Name (required)
   * Description
   * Access Type: Public / Private (required)
     * Public - Public subnets can be accessed through the internet. Public IP addresses that you want to assign to your publicly accessible VMs can only be assigned to this type of subnet
     * Private - Private subnets cannot be accessed through the internet. Only private IP addresses will be created inside this subnet, and you can only add privately accessible VMs inside this subnet
   * CIDR (required)
     * CIDR means Classless Inter-Domain Routing. It’s notation to define the range of IP addresses for your subnet. It also defines how big your subnet is. For more details, check the section below
   * Gateway IP (required)
     * It's the IP address used by instances in the subnet to send traffic outside the subnet (like to the internet or other subnets). It’s mainly used for:
       * Routing internal traffic or
       * Connecting to the internet via an internet or NAT gateway, or
       * Being the default route in the route table for resources in the subnet
4. If no VPC exists, → option to create one in the pop-up
5. Click **"Create Subnet"**
6. Subnet appears in the list with its properties

***

#### Deleting a Subnet <a href="#deleting-a-subnet" id="deleting-a-subnet"></a>

You can only delete a subnet **if it is not attached to any VM**. Here's how the process works:

**Pre-check**

* If the subnet **is currently attached to any VM**, the UI will:
  * **Block deletion**
  * Show a warning:

    ❌ "Subnet is in use by one or more Virtual Machines. Please detach all VMs before deleting the subnet."

***

**If Subnet is NOT attached:**

1. Navigate to **Networking > Subnets**
2. Click on the **three-dot menu** next to the subnet you want to delete
3. Select **"Delete Subnet"**
4. A confirmation dialog appears with a caution:

   ⚠️ "Deleting this subnet is irreversible and will remove the subnet and all its route table associations."
5. To confirm, you must **type the subnet name manually** (copy-paste disabled)
6. If the entered name matches:
   * Subnet is deleted successfully
   * Toast: “Subnet deleted successfully”
7. If mismatch:
   * Toast: “Entered name does not match. Deletion cancelled”

#### Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

Subnets are completely free, and you won’t be charged for any subnets


# CIDR (Classless Inter-Domain Routing)

## Understanding CIDR

**CIDR (Classless Inter-Domain Routing)** is a method for allocating IP addresses and routing traffic. Unlike older class-based addressing (Class A, B, C), CIDR enables more flexible and efficient allocation of IP addresses using **prefix notation**, such as:

```
192.168.1.0/24
```

In CIDR, the number following the slash (e.g., `/24`) is the **network prefix**, which determines how many IP addresses are included in the subnet range.

***

### Why is CIDR Important?

When creating a subnet, you must define how many IP addresses should be available for resources within that subnet. CIDR notation gives you precise control over subnet sizing, allowing you to balance between:

* **Small subnets** – e.g., `/30` for limited usage scenarios
* **Large subnets** – e.g., `/16` for high-scale deployments

Choosing the right CIDR size ensures efficient use of IP space while minimizing waste.

***

### CIDR Size Table

| CIDR Notation | Number of IPs | Usable IPs | Subnet Mask     | Example Range                 |
| ------------- | ------------- | ---------- | --------------- | ----------------------------- |
| /32           | 1             | 0          | 255.255.255.255 | 192.168.1.1                   |
| /30           | 4             | 2          | 255.255.255.252 | 192.168.1.0 – 192.168.1.3     |
| /29           | 8             | 6          | 255.255.255.248 | 192.168.1.0 – 192.168.1.7     |
| /28           | 16            | 14         | 255.255.255.240 | 192.168.1.0 – 192.168.1.15    |
| /27           | 32            | 30         | 255.255.255.224 | 192.168.1.0 – 192.168.1.31    |
| /26           | 64            | 62         | 255.255.255.192 | 192.168.1.0 – 192.168.1.63    |
| /24           | 256           | 254        | 255.255.255.0   | 192.168.1.0 – 192.168.1.255   |
| /23           | 512           | 510        | 255.255.254.0   | 192.168.0.0 – 192.168.1.255   |
| /22           | 1,024         | 1,022      | 255.255.252.0   | 192.168.0.0 – 192.168.3.255   |
| /21           | 2,048         | 2,046      | 255.255.248.0   | 192.168.0.0 – 192.168.7.255   |
| /20           | 4,096         | 4,094      | 255.255.240.0   | 192.168.0.0 – 192.168.15.255  |
| /16           | 65,536        | 65,534     | 255.255.0.0     | 192.168.0.0 – 192.168.255.255 |

> **Note**: The number of usable IPs is always 2 less than the total IPs — one is reserved as the network address and the other as the broadcast address.

***

### Choosing the Right CIDR Block

When selecting a CIDR block, use the following general guidance:

* Use `/30` or `/29` for **small setups** (e.g., 1–6 VMs)
* Use `/27` or `/26` for **medium setups** (e.g., 30–60 VMs)
* Use `/24` or `/23` for **large-scale environments**

{% hint style="info" %}
For most users, `/28` or `/27` is a good starting point unless larger address space is explicitly required.
{% endhint %}


# Security Groups

A **Security Group** defines inbound and outbound traffic rules for resources like VMs.

* Acts like a virtual firewall
* Attached at a VPC level but to a VM

In the same analogy of VPC to a neighborhood, assume that you are putting a security guard in front of your houses (VMs in this case) who decides who goes into the house or can come out of the house; that’s exactly a security group. The simplest use of security groups is to enable inbound and outbound traffic through ports (Port 22, 8080, etc).

Please note that Port 22 or SSH protocol should be enabled if you want to SSH into the VMs

***

#### Creating a Security Group  <a href="#creating-a-security-group" id="creating-a-security-group"></a>

1. Navigate to **Networking > Security Groups**
2. Click **"Create Security Group"**
3. Fill in:
   * Name
   * Description
   * VPC (required)
   * Define Inbound Rules:
     * Protocol
     * Port Range

       * Based on the selected protocols, the standard defined port ranges will be auto-selected
       * You can skip the protocol and just mention the port ranges
       * All port ranges should be mentioned in comma comma-separated list. E.g.; 22, 80, 8080, 1205-1250
       * You can define as many ports as you want, unless a protocol is selected.

       &#x20;      Follow the principle of least privilege:

       * Only open required ports
       * Restrict access to known IP ranges
       * Avoid broad port ranges unless necessary
     * Remote IP Prefix

       `⚠️ Warning:`

       Allowing 0.0.0.0/0 exposes your resource to the public internet.\
       Avoid opening sensitive ports like SSH (22) unless restricted to specific IPs.
   * Define Outbound Rules (similar)
   * If no inbound rules are defined, all inbound traffic is denied by default.
4. Click **"Create Security Group":**

**Example** (Secure SSH access):

* Protocol: TCP
* Port: 22
* Source: Your IP (e.g., 203.0.113.5/32)

Example (Web server):

* HTTP: 80 from 0.0.0.0/0
* HTTPS: 443 from 0.0.0.0/0
* SSH: restricted to admin IP only

***

#### Editing a Security Group  <a href="#editing-a-security-group" id="editing-a-security-group"></a>

1. Click the **three-dot menu > Edit**
2. Name and VPC are not editable
3. All other fields (description, rules) can be changed
4. You can define new rules or edit existing rules or delete existing rules
5. Save changes

***

#### Deleting a Security Group <a href="#deleting-a-security-group" id="deleting-a-security-group"></a>

1. Click the **three-dot menu > Delete**
2. Confirm deletion in the pop-up
3. Upon confirmation, SG is deleted

***

#### Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

All Security groups are free and would not be chargeable.

***

### Protocols & Standard Port Ranges <a href="#protocols-and-standard-port-ranges" id="protocols-and-standard-port-ranges"></a>

| **Protocol**             | **Port(s)**                     | **Direction**    | **Use Case**                                                                                              |
| ------------------------ | ------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------- |
| **All**                  | `0-65535`                       | Inbound/Outbound | Allows all traffic. Use with caution.                                                                     |
| **TCP**                  | `0-65535` (customizable)        | Inbound/Outbound | Reliable communication (used by HTTP, SSH, RDP, etc.)                                                     |
| **UDP**                  | `0-65535` (customizable)        | Inbound/Outbound | Fast, connectionless (used by DNS, NTP, video/audio streaming)                                            |
| **DNS**                  | `UDP 53` / `TCP 53`             | Both             | Domain name resolution                                                                                    |
| **HTTP**                 | `TCP 80`                        | Inbound          | Unencrypted web traffic                                                                                   |
| **HTTPS**                | `TCP 443`                       | Inbound          | Encrypted web traffic                                                                                     |
| **ICMP**                 | N/A (uses Type/Code)            | Both             | Used for ping, traceroute                                                                                 |
| **FTP**                  | `TCP 20 (data)`, `21 (control)` | Inbound          | File transfer protocol                                                                                    |
| **SSH**                  | `TCP 22`                        | Inbound          | Secure shell remote login                                                                                 |
| **IMAP**                 | `TCP 143`                       | Inbound          | Email retrieval                                                                                           |
| **IMAPS**                | `TCP 993`                       | Inbound          | Secure email retrieval                                                                                    |
| **LDAP**                 | `TCP 389`                       | Inbound          | Directory services                                                                                        |
| **MSSQL**                | `TCP 1433`                      | Inbound          | Microsoft SQL Server                                                                                      |
| **MYSQL**                | `TCP 3306`                      | Inbound          | MySQL database                                                                                            |
| **POP3**                 | `TCP 110`                       | Inbound          | Email retrieval (older protocol)                                                                          |
| **POP3S**                | `TCP 995`                       | Inbound          | Secure version of POP3                                                                                    |
| **RDP**                  | `TCP 3389`                      | Inbound          | Remote Desktop Protocol (Windows)                                                                         |
| **SMTP (plain)**         | `TCP 25`                        | Inbound/Outbound | Legacy email sending. Often blocked by ISPs and prone to abuse (spam). Avoid using in production.         |
| **SMTPS (implicit TLS)** | `TCP 465`                       | Inbound          | Legacy secure SMTP over TLS. Still supported by some providers but not recommended as the primary option. |
| **SMTPS Submission**     | `TCP 587`                       | Inbound/Outbound | Recommended port for sending email using STARTTLS (secure and widely supported).                          |

* **All**: Opens all ports/protocols – best avoided unless debugging in a secure environment.
* **ICMP**: Doesn’t use ports. Controlled by ICMP types like Echo Request (type 8), Echo Reply (type 0).
* **Custom Rules**: You can specify any protocol and port range manually using TCP/UDP.
* Ports above `1024` are generally considered **ephemeral** or for custom application use.


# Static IP Addresses

**Static IP Addresses** are reserved IPs (currently only public IPv4) that can be associated with VMs. In the same analogy of the Neighbourhood for VPCs, an IP address is like the address number you can use to identify particular houses (In this case, VMs). By reserving a static IP address, you reserve a particular IP address that allows you to easily identify, connect to, or divert traffic to your VMs (House) using this reserved IP address consistently.

Any reserved static Public IP address, regardless of being used or not, will be priced at **Rs 0.28 per IP address per hour**.

***

#### Creating/Reserving an IP Address <a href="#creating-reserving-an-ip-address" id="creating-reserving-an-ip-address"></a>

1. Go to **Networking > Static IP Addresses**
2. Click **"Reserve IP Address."**
3. Choose:
   * Subnet (only Public subnets shown)
   * IP Type: IPv4 (IPv6 is disabled for now)
4. If no public subnet → option to create one
5. Click **"Reserve"** → IP is added to the table

You can now attach this IP address to any of your VMs

***

### Deleting/Unreserving an IP Address <a href="#deleting-unreserving-an-ip-address" id="deleting-unreserving-an-ip-address"></a>

When a static IP address is no longer needed (e.g., the associated VM, Load Balancer, or service has been deleted or reassigned), you can **unreserve** it. This action **removes the IP from your account's allocation**, freeing it for others in the cloud pool and stopping billing for it.

{% hint style="danger" %}
Once unreserved, the same IP cannot be reclaimed later unless it is still available in the pool, which is not guaranteed.
{% endhint %}

#### Steps to Delete or Unreserve an IP <a href="#steps-to-delete-or-unreserve-an-ip" id="steps-to-delete-or-unreserve-an-ip"></a>

1. **Go to the Static IP address Page** in the Console.
2. Locate the **IP address** you want to delete/unreserve.
3. Confirm the IP is **not currently attached** to any:
   * VM instance
4. Click **"Unreserve."**
5. Confirm the action in the prompt.

Once confirmed:

* The IP will be removed from your project/account.
* It will return to the general pool of available IPs.
* You will **no longer be charged** for the reservation.

#### Preconditions <a href="#preconditions" id="preconditions"></a>

* You **must detach** the IP from any active resource before unreserving it.
* If the IP is attached, the system will prevent deletion and may show an error such as:

***

#### &#x20;Billing and Pricing <a href="#billing-and-pricing" id="billing-and-pricing"></a>

Static Public IP addresses are priced at **Rs 0.28 per IP address per hour**. You will be charged the same price regardless of whether it’s attached to a VM or not. You won’t be charged for any private IP addresses


# Load Balancers

### Introduction

Krutrim Load Balancers are fully managed, high-availability services that automatically distribute incoming traffic across your backend servers or applications. They ensure your services stay reliable, responsive, and scalable — even during sudden traffic spikes.

Load balancers act as smart traffic managers, routing requests to healthy targets and preventing any single server or region from becoming a point of failure. Whether you’re running web apps, APIs, or large-scale workloads, Krutrim’s Load Balancers help maintain consistent performance and uptime.

You can choose between:

* **Application Load Balancers (ALB)** — operate at Layer 7 for content-based routing (HTTP/HTTPS).
* **Network Load Balancers (NLB)** — operate at Layer 4 for ultra-low-latency traffic (TCP/UDP).

Krutrim manages scaling, health checks, SSL termination, and high availability automatically — so you can focus on your applications, not the infrastructure behind them.

#### Target Groups

A **Target Group** is a logical collection of backend servers (VMs) that receive traffic from a Load Balancer. Each target group defines how the health of its targets is checked and which ports or protocols are used for communication.

* Targets are registered VMs or services that handle actual user requests.
* Health checks ensure only healthy targets receive traffic.
* You can attach one or more target groups to a load balancer, depending on your routing needs.

#### Listeners

A **Listener** is a process that checks for incoming connection requests using a specific protocol and port. It defines *how* and *where* incoming traffic is routed.

* Each listener is mapped to only *one* target group.
* You can add multiple listeners (e.g., HTTP on port 80, HTTPS on port 443) to the same load balancer.
* You can add multiple listeners using the same protocol (eg. HTTP, HTTPS, TCP), but on different ports. Each of these would map to a separate target group.

#### Choosing the Right Load Balancer

Krutrim offers two types of load balancers to suit different application needs. The choice depends on the kind of traffic your application handles and how you want to route it.&#x20;

Choose **Application Load Balancer (ALB)** if you need to route web traffic intelligently — for example, directing requests based on URLs, headers, or cookies. It’s ideal for websites, APIs, and micro-services that use HTTP or HTTPS.

Choose **Network Load Balancer (NLB)** if you need ultra-fast performance and can handle raw network traffic without content-based routing. It’s best for real-time applications, gaming, streaming, or IoT workloads that rely on TCP or UDP connections.

|                      | ALB                                            | NLB                                    |
| -------------------- | ---------------------------------------------- | -------------------------------------- |
| **Best For**         | Web applications, APIs, microservices          | Real-time apps, gaming, streaming, IoT |
| **Traffic Type**     | HTTP / HTTPS                                   | TCP / UDP                              |
| **Routing Type**     | Content-based (based on URL, headers, cookies) | Network-based (based on IP and port)   |
| **SSL Termination**  | Yes – SSL handled at the load balancer         | No – traffic passed as-is              |
| **Policies & Rules** | Supports advanced routing rules                | Not applicable                         |

### Creating a Target Group

Creating a target group is a pre-requisite for creating a load balancer.

[Learn how to create a Target Group.](/basics/core-infrastructure/networking/load-balancers/create-target-group)

### Creating a Load Balancer

[Learn how to create a Network Load Balancer.](/basics/core-infrastructure/networking/load-balancers/create-network-load-balancer-nlb)

[Learn how to create an Application Load Balancer.](/basics/core-infrastructure/networking/load-balancers/create-application-load-balancer-alb)

### Manage Load Balancer

* You can view or edit a Load Balancer from the **Load Balancers** listing page by clicking **“View”** or **“Edit”** next to the desired Load Balancer.
* **Region**, **VPC**, and **Subnet** cannot be modified after deployment.
* **Security Groups** can be updated or changed anytime.
* In **Listener** settings, the **Protocol** and **Port number** cannot be modified once deployed. However, all **Policies** and **Rules** under a listener can be edited as needed.
* In **Pool Configuration**, you can modify the **Pool Name**, **Load Balancing Algorithm**, and **Target Group** attached. The **Pool Protocol**, however, cannot be changed.
* For major changes like switching protocol or region, it’s recommended to create a new Load Balancer.

### Delete Load Balancer

* You can delete a Load Balancer from the **Load Balancers** listing page by selecting the **“Delete”** option from the **Actions** menu of the respective Load Balancer.
* Deleting a Load Balancer will **not delete the associated Target Groups** — they will only be **detached** and remain available for future use.
* Once deleted, the Load Balancer and its listeners, pools, and policies are permanently removed.
* Always verify that no active applications depend on the Load Balancer before deleting it.

### Billing

* The **base charge** for both Standard ALB and Standard NLB is **₹8.00 per hour**.
* **Data processing charges** apply as follows: **₹0.44/GB** for the first 100 GB, and **₹0.22/GB** for usage above 100 GB.
* A **Standard ALB** supports up to **10,000 simultaneous connections** and **40,000 requests per second (RPS)**.
* A **Standard NLB** supports up to **90,000 simultaneous connections** and **350,000 requests per second (RPS)**.
* Data transfer is billed for both **inbound and outbound** traffic through the load balancer.


# Create Target Group

1. Go to the **“Networking > Load Balancing > Target Groups”** tab.
2. Click **“Create Target Group.”**
3. Fill in:
   * **Target Group Name** (required)
   * **VPC** (required)
4. Configure **Health Checks** to ensure only healthy targets receive traffic:
   * **Health Check Name**
   * **Health Check Protocol** (HTTP, TCP)
   * **Health Check Path** *(for HTTP) -* this is the endpoint the load balancer periodically calls to check if your backend is healthy.
   * **Health Check Interval** (time between checks)
   * **Timeout** (max wait time for a response)
   * **Max Retries** (number of failed checks before marking unhealthy)
5. Under **Select Targets**, choose one or more active VMs to add to the target group.
   * Only healthy and active VMs can be added.
   * The target group must contain at least 1 VM, in order to be attached to a load balancer.
   * Enter the Port Number for target traffic.
6. Click **“Create Target Group.”**

{% hint style="danger" %}
Make sure the port is open in your target’s **security group**, otherwise health checks and traffic routing may fail.
{% endhint %}

### Edit Target Group

You can edit the following characteristics of a target group:

* Health Check Name, Path, Interval, Timeout, Max Retries
* Targets comprising the target group
* Port Number for the target group

{% hint style="info" %}
You cannot modify the Target Group Name, VPC or the Health Check Protocol after deployment.
{% endhint %}


# Create Network Load Balancer (NLB)

{% hint style="info" %}
Creating a Target Group is a prerequisite for creating a Load Balancer. [Learn how to create a target group](/basics/core-infrastructure/networking/load-balancers/create-target-group)
{% endhint %}

* Go to the "Networking > Load Balancers" tab.
* Click on "Create Load Balancer > Network Load Balancer".
* Fill in the following fields:
  * Load Balancer Name - a display name for your LB
  * Description
  * Region - select the region where you want to deploy your LB
  * VPC, Subnet - select the VPC and Subnet within which you want to place your LB
  * Security Group - Choose a security group for your LB. You can create a new security group with custom inbound/outbound rules for your LB, from the "Networking > Security Groups" tab. [Learn how to create a security group.](/basics/core-infrastructure/networking/security-groups)
* Select a performance tier. We provide the following performance tiers:
  * **Standard** - 4 vCPUs, 8 GB RAM
  * **Pro (coming soon)** - 8 vCPUs, 16 GB RAM&#x20;

{% hint style="success" %}
A **Standard** NLB can support upto 90,000 simultaneous connections and 350,000 requests per second (RPS).
{% endhint %}

* **High Availability** - Each load balancer is provisioned with High Availability (HA) by default. The load balancer is provisioned with 2 nodes (1 primary, 1 backup) for enhanced reliability and fault tolerance.
* **Add Listeners** - You can add multiple listeners, each of which maps to 1 target group.
  * Fill in a display name, the protocol, and port number on which it listens for traffic.
* **Pool Configuration** -&#x20;
  * Add a display name and protocol for your pool.
  * Select a load balancer algorithm appropriate for your needs.
  * Select a target group containing at least 1 active VM, for your pool.

| Algorithm             | Description                                                                                                                                 |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Round Robin**       | Distributes requests evenly across all healthy targets — simple and effective for most workloads.                                           |
| **Least Connections** | Sends new requests to the target with the fewest active connections — best for apps where requests vary in duration.                        |
| **Source IP**         | Routes traffic based on the client’s IP address — ensures requests from the same client always go to the same target (session consistency). |


# Create Application Load Balancer (ALB)

{% hint style="info" %}
Creating a Target Group is a prerequisite for creating a Load Balancer. [Learn how to create a target group](/basics/core-infrastructure/networking/load-balancers/create-target-group)
{% endhint %}

* Go to the "Networking > Load Balancers" tab.
* Click on "Create Load Balancer > Application Load Balancer".
* Fill in the following fields:
  * Load Balancer Name - a display name for your LB
  * Description
  * Region - select the region where you want to deploy your LB
  * VPC, Subnet - select the VPC and Subnet within which you want to place your LB
  * Security Group - Choose a security group for your LB. You can create a new security group with custom inbound/outbound rules for your LB, from the "Networking > Security Groups" tab. [Learn how to create a security group.](/basics/core-infrastructure/networking/security-groups)
* Select a performance tier. We provide the following performance tiers:
  * **Standard** - 4 vCPUs, 8 GB RAM
  * **Pro (coming soon)** - 8 vCPUs, 16 GB RAM&#x20;

{% hint style="success" %}
A **Standard** ALB can support upto 10,000 simultaneous connections and 40,000 requests per second (RPS).
{% endhint %}

* **High Availability** - Each load balancer is provisioned with High Availability (HA) by default. The load balancer is provisioned with 2 nodes (1 primary, 1 backup) for enhanced reliability and fault tolerance.
* **Add Listeners** - You can add multiple listeners, each of which maps to 1 target group.
  * Fill in a display name, the protocol, and port number on which it listens for traffic.
  * **Policies & Rules** - An ALB can route requests according to their content, hence we have the option of adding a policy for each listener, and rules within the policy. A policy defines the action to take when all associated rules evaluate to true. Rules define the specific conditions (e.g., URL path, headers) to match client requests.
  * Fill in a display name for your policy.
  * Select the action to take when all rules evaluate to true:
    1. **Redirect to URL** - Redirect all matching requests to a specified URL
    2. **Reject** - Reject all matching requests.
    3. **Redirect to Pool** - Forward all matching requests to the target group.
* **Add Rules** - You can add multiple rules inside a listener's policy, of the following types:

| Rule Type                             | Description                                                                                                                                                                |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Cookie**                            | Routes requests based on specific cookie values. Useful for session-based routing or user personalisation (e.g., send users with a certain cookie to a specific backend).  |
| **File Type**                         | Routes requests depending on the file extension in the URL (e.g., `.jpg`, `.css`, `.mp4`). Useful for separating static and dynamic content.                               |
| **Header**                            | Routes traffic based on HTTP header values. Ideal for routing based on user-agent, content-type, or custom headers set by the client.                                      |
| **Host Name**                         | Routes requests based on the domain name in the request (e.g., `api.example.com`, `app.example.com`). Perfect for hosting multiple domains on one load balancer.           |
| **Path**                              | Routes traffic according to the URL path (e.g., `/api/*`, `/images/*`). Commonly used to direct requests for different parts of an app to specific target groups.          |
| **SSL Connection (Has Certificate)**  | Checks whether the incoming SSL/TLS connection includes a valid certificate. Useful for enforcing secure client connections (mutual TLS).                                  |
| **SSL (Verify Result)**               | Routes based on the result of SSL certificate verification (valid/invalid). Allows you to handle unverified or expired certificates separately.                            |
| **SSL Distinguished Name (DN) Field** | Routes based on details within the SSL certificate’s Distinguished Name (e.g., Common Name or Organization). Useful in enterprise setups for identifying specific clients. |

* Select an appropriate comparator and fill in the value to compare against.
* **Pool Configuration** -&#x20;
  * Add a display name and protocol for your pool.
  * Select a load balancer algorithm appropriate for your needs.
  * Select a target group containing at least 1 active VM, for your pool.

| Algorithm             | Description                                                                                                                                 |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Round Robin**       | Distributes requests evenly across all healthy targets — simple and effective for most workloads.                                           |
| **Least Connections** | Sends new requests to the target with the fewest active connections — best for apps where requests vary in duration.                        |
| **Source IP**         | Routes traffic based on the client’s IP address — ensures requests from the same client always go to the same target (session consistency). |


# DNS

Krutrim Cloud DNS is a fully managed, scalable, and high-performance Domain Name System (DNS) service. It enables you to create and manage **hosted zones**, configure DNS records, and route user requests to your applications and workloads running on Krutrim Cloud.

By integrating DNS management directly within the platform, you can connect your domains, APIs, and services to the internet or internal VPCs without relying on external DNS providers.

***

### Introduction

#### What is Krutrim Cloud DNS?

Krutrim Cloud DNS provides domain name resolution for your hosted workloads. It converts user-friendly domain names like `example.com` into IP addresses that computers use to communicate.

The service offers:

* **Managed Public and Private Hosted Zones**
* **Support for all standard DNS record types**
* **Advanced Routing Policies** (Simple, Weighted, GeoIP, Health Checks)

***

### Core Concepts

#### DNS and Hosted Zones

A **domain** (e.g., `example.com`) is a unique name on the internet.\
A **hosted zone** is a container for the DNS records associated with that domain.

Krutrim Cloud DNS supports:

* **Public Hosted Zones (coming soon)** – Resolve names over the internet.
* **Private Hosted Zones** – Resolve names only within your selected VPCs. You can attach multiple VPCs to a private hosted zone.

***

#### Supported DNS Record Types

| Record Type | Description                                        | Example                               |
| ----------- | -------------------------------------------------- | ------------------------------------- |
| **A**       | Maps a domain name to an IPv4 address              | `example.com → 192.0.2.1`             |
| **AAAA**    | Maps a domain name to an IPv6 address              | `example.com → 2001:db8::1`           |
| **CNAME**   | Creates an alias to another domain                 | `www.example.com → example.com`       |
| **MX**      | Routes email to mail servers                       | `example.com → mail.example.com`      |
| **TXT**     | Stores text data, e.g. verification or SPF records | `v=spf1 include:_spf.google.com ~all` |
| **NS**      | Defines the authoritative nameservers              | `ns1.krutrim.cloud.`                  |

***

#### Routing Protocols

| Protocol       | Description                                                                                                                                                                                                                                                                                        | When to Use                                                                                                                     |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Simple**     | Sends all traffic to a single IP address. This is the default and easiest routing option.                                                                                                                                                                                                          | Use when you have one server or endpoint handling all user requests.                                                            |
| **Weighted**   | Splits traffic between multiple IP addresses based on the weight you assign to each one. Higher weight means more traffic goes to that server.                                                                                                                                                     | Use when you want to distribute traffic unevenly between servers — for example, to send more users to a higher-capacity server. |
| **GeoIP**      | Routes users based on their location, such as country or region. Each location can be mapped to a specific server or IP.                                                                                                                                                                           | Use when you want users to connect to the nearest data center for better speed and performance.                                 |
| **HealthPort** | Routes traffic only to servers that are healthy and actively responding on a specific port. Supports both load balancing and failover by using **Primary** and **Secondary IP sets** — traffic goes to primary IPs under normal conditions and switches to secondary IPs if the primary ones fail. | Use when you need high availability and automatic failover between servers, such as for critical web or application services.   |
| **HealthURL**  | Checks the health of a server through an HTTP or HTTPS endpoint before routing traffic to it. If the endpoint is unavailable, traffic is redirected elsewhere.                                                                                                                                     | Use for web applications or APIs where you want routing decisions based on real-time application health.                        |

> Advanced routing applies to **A** and **AAAA** records only.

***

### Getting Started

#### Create a Hosted Zone

1. Go to **Networking → DNS** in the Krutrim Cloud Console.
2. Click **Create Hosted Zone**.
3. Enter your **Domain Name** (e.g., `example.com`).
4. Choose **Public** or **Private**:
   * **Public (coming soon)**: Accessible over the internet
   * **Private**: Accessible only within a selected VPC
5. (If Private) Select the VPC.
6. Click **Create**.

***

#### Add DNS Records

Once the hosted zone is created:

1. Open the hosted zone management page from the DNS dashboard.
2. Go to **Add Record**.
3. Select record type (A, CNAME, MX, TXT, etc.).
4. Fill in the fields:
   * **Record Name**
   * **Record Value(s)**
   * **TTL**
   * **Routing Protocol** (for A/AAAA)
5. Click **Save Record**.
6. You can edit records from their entries in the DNS records table.

### Managing Hosted Zones

#### View Hosted Zones

From the **Hosted Zones** landing page, you can:

* View all your zones with filters for Public/Private
* See record counts, type, and creation date
* Manage or delete zones

#### Associate multiple VPCs with Private Zone

1. Open a private hosted zone.
2. Click **Attach VPC**.
3. Select the desired VPC and save.

{% hint style="info" %}
Only resources inside associated VPCs can resolve records from a private zone.
{% endhint %}

***

### Best Practices

* **Use low TTLs (60–300s)** for frequently updated records.
* **Use Weighted routing** for smooth traffic distribution.
* **Avoid overlapping private zones** across VPCs.
* **Leverage HealthPort/HealthURL** for high availability.
* **Review records periodically** to remove unused entries.

***

### Billing

| Service                    | Flavor          | Unit                | Price / Hour | Price / Month |
| -------------------------- | --------------- | ------------------- | ------------ | ------------- |
| DNS Base Charge - Per zone | Upto 25         | Hour                | ₹0.031       | ₹22.04        |
| DNS Base Charge - Per zone | Above 25        | Hour                | ₹0.012       | ₹8.81         |
| DNS Zones - Query Charges  | Upto 1 Billion  | per million queries | --           | ₹35.26        |
| DNS Zones - Query Charges  | Above 1 Billion | per million queries | --           | ₹17.63        |


# Billing for Networking

| Service                    | Flavor                                        | Unit                | Price / Hour | Price / Month |
| -------------------------- | --------------------------------------------- | ------------------- | ------------ | ------------- |
| VPC                        | *Charges apply  once resources are attached.* | Hour                | ₹0.28        | ₹204          |
| IP Addresses               | Floating IP                                   | Hour                | ₹0.28        | ₹204          |
| DNS Base Charge - Per Zone | Up to 25                                      | Hour                | ₹0.031       | ₹22.04        |
| DNS Base Charge - Per Zone | Above 25                                      | Hour                | ₹0.012       | ₹8.81         |
| DNS Zones - Query Charges  | Up to 1 Billion                               | Per million queries | —            | ₹35.26        |
| DNS Zones - Query Charges  | Above 1 Billion                               | Per million queries | —            | ₹17.63        |


# Krutrim Kubernetes System


# Creating Cluster

This guide walks you through creating a Kubernetes cluster using the Krutrim Kubernetes Service.

### Before You Begin

Ensure you have:

* [ ] A VPC created in your Krutrim Cloud account
* [ ] At least one subnet configured in your VPC
* [ ] Understanding of your [network configuration requirements](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/network-configuration)
* [ ] Decided on your cluster's purpose (development, staging, production)

### Cluster Configuration

When creating a cluster, you'll need to configure the following settings:

**Basic Settings:**

* Cluster Name: Choose a descriptive name for your cluster.
* Kubernetes Version:
  * Select the Kubernetes version for your cluster:
    * **Recommended**: Use the default version of Krutrim Kubernetes Service
    * **Specific Version**: Choose if you have application compatibility requirements

{% hint style="info" %}
**Note**: You can upgrade the Kubernetes version later, but you cannot downgrade.
{% endhint %}

**Network Configurations**

* VPC Configuration:&#x20;
  * Select the VPC you want your cluster to be in
  * This defines the network boundary for your cluster
* Subnet Configuration:&#x20;
  * Specify the subnet where your cluster resources will be deployed
  * Ensure the subnet has sufficient IP addresses
  * **Important**: This subnet is used for LoadBalancer IP allocation

**LoadBalancer IP Usage**:

```
Every time you create a LoadBalancer Service:
├─ One IP address is allocated from this subnet
├─ The IP is taken from your subnet's available pool
└─ Plan accordingly for your expected LoadBalancer count
```

### Kubernetes Network Configuration

**Pod CIDR**

* Default: `192.168.0.0/16`
* Understanding Pod CIDR:
  * This CIDR is the IP range for pods in your cluster
  * Each node receives a /24 subnet (256 IPs) from this CIDR range
  * Capacity: `/16` = 256 nodes max, `/18` = 64 nodes max, `/20` = 16 nodes max
* Pod CIDR cannot be changed after cluster creation. Plan for future growth!

Examples:

```yaml
# Small cluster (up to 16 nodes)
Pod CIDR: 192.168.0.0/20

# Medium cluster (up to 64 nodes)
Pod CIDR: 192.168.0.0/18

# Large cluster (up to 256 nodes)
Pod CIDR: 192.168.0.0/16
```

**Calculation:**

```
Pod CIDR: 192.168.0.0/16
├─ Total IPs: 65,536
├─ Per-node allocation: /24 (256 IPs)
├─ Maximum nodes: 256
└─ Maximum pods per node: ~250 (after system overhead)
```

{% hint style="warning" %}
**Reserved Range**: Cannot use `172.24.0.0/13` (reserved for system use)
{% endhint %}

**Service CIDR**

* Default: `10.100.0.0/16`
* Understanding Service CIDR:
  * This CIDR is the IP range for Kubernetes Services (ClusterIP, NodePort, LoadBalancer)
  * Each Service consumes one IP from this range
* Service CIDR must not overlap with Pod CIDR

Examples:

```yaml
# Standard configuration (65,536 service IPs)
Service CIDR: 10.100.0.0/16

# Smaller deployments (4,096 service IPs)
Service CIDR: 10.100.0.0/20
```

{% hint style="warning" %}
**Reserved Range**: Cannot use `172.24.0.0/13` (reserved for system use)
{% endhint %}

### Network Configuration Examples

**Development/Testing Cluster**:

```yaml
Cluster Name: dev-k8s-cluster
VPC: Select your dev VPC
Subnet: Select subnet with at least 100 available IPs
Pod CIDR: 192.168.0.0/20  # Supports up to 16 nodes
Service CIDR: 10.100.0.0/20  # Supports 4,096 services
```

**Production Cluster**:

```yaml
Cluster Name: prod-web-cluster
VPC: Select your production VPC
Subnet: Select subnet with at least 200 available IPs
Pod CIDR: 192.168.0.0/16  # Supports up to 256 nodes
Service CIDR: 10.100.0.0/16  # Supports 65,536 services
```

## Cluster Creation Process

After submitting your cluster configuration:

### Verification Checklist

Before creating the cluster, verify:

* [ ] Cluster name follows naming conventions
* [ ] Kubernetes version is appropriate
* [ ] VPC and subnet are correctly specified
* [ ] Pod CIDR matches your scale requirements
* [ ] Service CIDR doesn't overlap with Pod CIDR or Node Subnet
* [ ] Network capacity is sufficient

**Network Capacity Planning**:

```
Question: How many nodes do I plan to run?
Answer: ____ nodes

Required Pod CIDR:
- Up to 16 nodes → /20 or larger
- Up to 64 nodes → /18 or larger
- Up to 256 nodes → /16 or larger
```

### Cluster Creation Stages

{% stepper %}
{% step %}

### Creating

Initial resources are being provisioned.

* Timeline (part of total): Initial setup — 1-2 minutes
  {% endstep %}

{% step %}

### Provisioning

Control plane, network, and integrations are being configured.

* Timeline (part of total): Control plane provisioning — 2-3 minutes; Network configuration — 1-2 minutes
  {% endstep %}

{% step %}

### Provisioned

Cluster is ready. Wait until status shows `PROVISIONED` before creating node groups.
{% endstep %}
{% endstepper %}

**Overall Timeline**:

* Total time: Approximately 5-8 minutes

**What's Happening**:

{% stepper %}
{% step %}
Control plane is being created
{% endstep %}

{% step %}
Network resources are being configured
{% endstep %}

{% step %}
OpenStack integration is being set up
{% endstep %}

{% step %}
Core infrastructure components are being installed
{% endstep %}
{% endstepper %}

**Monitoring Status**:

* Cluster status transitions: `CREATING` → `PROVISIONING` → `PROVISIONED`
* Monitor the cluster status to track progress

⚠️ **Important**: Do not create node groups until the cluster status is `PROVISIONED`

## Next Steps After Cluster Creation

### Create Initial Node Groups

Once your cluster is provisioned, you need to create node groups to run your workloads.

**Critical First Step**: Create at least 1-2 nodes **without taints** to ensure system components can be scheduled.

**Why This Matters**:

```
Essential add-ons that need to be scheduled:
├─ CoreDNS (DNS resolution for the cluster)
└─ Cilium (CNI for pod networking)

If all nodes have taints:
├─ These add-ons cannot be scheduled
├─ Cluster remains in non-functional state
└─ Pods cannot start or communicate
```

**Recommended Approach**:

{% stepper %}
{% step %}

### Create Initial Node Group (without taints)

Example configuration:

```yaml
Name: general-nodes
Instance Type: 4vcpu-8gb or larger
Min Size: 1
Max Size: 3
Desired Size: 2
Taints: None
Labels:
  workload-type: general
```

{% endstep %}

{% step %}

### Create Additional Node Groups (with or without taints)

Example configuration:

```yaml
Name: workload-nodes
Instance Type: 4vcpu-8gb or larger
Min Size: 2
Max Size: 10
Desired Size: 3
Taints: Optional (based on workload requirements)
Labels:
  workload-type: application
```

{% endstep %}
{% endstepper %}

See [Managing Node Groups](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/managing-nodegroups) for detailed instructions.

### Install Add-ons

After creating node groups, install necessary add-ons for your cluster.

#### Essential Add-ons

**CoreDNS**:

* Provides DNS service for the cluster
* Required for service discovery
* Must be installed manually
* You can choose to install your own cluster DNS service also

### CNI (Container Network Interface) - REQUIRED

You must install a CNI for pod networking:

**Option 1: Cilium (Recommended)**:

* Optimized for Krutrim Cloud
* eBPF-based networking
* High performance and security
* **Important**: Do NOT install kube-proxy if using Cilium

**Option 2: Your Own CNI**:

* You can install kube-proxy
* Then install your preferred CNI solution
* Note: Our Cilium add-on may not work with kube-proxy

**CNI Installation Priority**:

```
1. Install Cilium (Krutrim optimized) - WITHOUT kube-proxy
   OR
2. Install kube-proxy first, then your own CNI solution
```

See [Installing Add-ons](broken://pages/1279ed917fcd47b1b408ede27aea9c58a949e7ed) for detailed instructions.

### Access Your Cluster

Once all components are installed, you can access your cluster using the kubeconfig file.

**Obtain Kubeconfig**:

* Retrieve the kubeconfig file for your cluster
* Save the file securely (this contains cluster access credentials)

**Verify Cluster Access**:

```bash
export KUBECONFIG=/path/to/downloaded-kubeconfig
kubectl cluster-info
```

**Check Node Status**:

```bash
kubectl get nodes
```

Expected output:

```
NAME                STATUS   ROLES    AGE   VERSION
node-1              Ready    <none>   5m    v1.31.0
node-2              Ready    <none>   5m    v1.31.0
node-3              Ready    <none>   3m    v1.31.0
```

**Verify System Pods**:

```bash
kubectl get pods -A
```

All pods should be in `Running` state:

```
NAMESPACE     NAME                        READY   STATUS    RESTARTS   AGE
kube-system   coredns-xxx                 1/1     Running   0          10m
kube-system   cilium-xxx                  1/1     Running   0          8m
kube-system   konnectivity-agent-xxx      1/1     Running   0          10m
```

## Common Issues During Creation

<details>

<summary>Issue: Cluster Stuck in CREATING</summary>

**Possible Causes**:

* VPC or subnet validation issues
* Network connectivity problems
* Resource quota limits

**Solution**:

1. Check if VPC and subnet are accessible
2. Verify your account has sufficient quota
3. Contact support if issue persists

</details>

<details>

<summary>Issue: Node Groups Not Creating</summary>

**Possible Causes**:

* Cluster not yet in PROVISIONED state
* Insufficient subnet IPs
* Invalid node configuration
* Resource issue within Krutrim Cloud

**Solution**:

1. Wait for cluster to reach PROVISIONED state
2. Verify subnet has available IPs
3. Check node group configuration
4. Contact support if issue persists

</details>

<details>

<summary>Issue: Pods Not Starting</summary>

**Possible Causes**:

* CNI not installed
* All nodes have taints
* No nodes without taints available

**Solution**:

1. Install Cilium or your CNI
2. Ensure at least 1-2 nodes without taints exist
3. Verify node status with `kubectl get nodes`

</details>

## Best Practices for Cluster Creation

### ✅ Do's

1. Plan Network Ranges:
   * Calculate required nodes before choosing Pod CIDR
   * Use default CIDRs unless you have specific requirements
   * Ensure no overlap between Pod and Service CIDRs
2. Create Untainted Nodes First:
   * Always create 1-2 nodes without taints
   * Use appropriate sizing (minimum 2vcpu-4gb)
   * Wait for nodes to be ready before deploying workloads
3. Install CNI Immediately:
   * Install Cilium or your CNI right after node creation
   * Verify all nodes reach Ready state
   * Check that all system pods are running
4. Use Descriptive Names:
   * Include environment in name (dev, staging, prod)
   * Include purpose (web, api, data)
   * Use consistent naming conventions
5. Plan for Growth:
   * Choose Pod CIDR with room for expansion
   * Ensure subnet has sufficient IPs for future LoadBalancers
   * Consider future node group additions

### ❌ Don'ts

1. Don't Use Small Pod CIDRs:
   * Avoid /24 or /22 for production
   * Don't underestimate growth
2. Don't Forget Untainted Nodes:
   * Never create only tainted nodes
   * Don't skip CoreDNS verification
3. Don't Mix CNI Strategies:
   * Don't install both Cilium and kube-proxy
   * Choose one networking approach
4. Don't Use Reserved Ranges:
   * Avoid 172.24.0.0/13 for Pod or Service CIDR
   * Check for conflicts with existing infrastructure

## Next Steps

After successfully creating your cluster:

1. [Configure Storage](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/storage-configuration) - Set up persistent storage for your applications
2. [Create Load Balancers](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/load-balancers) - Expose your services to the internet
3. [Learn Best Practices](broken://pages/43ad3c021a5a7766c22bac0cd782498f73bac782) - Optimize your cluster for production use

## Additional Resources

* [Troubleshooting Guide](broken://pages/46eccee5c14742b6ef6fa7e118ae1e6bb7703515) - Common issues and solutions
* [Network Configuration](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/network-configuration) - Detailed network planning
* [Managing Node Groups](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/managing-nodegroups) - Node group configuration
* [Installing Add-ons](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/installing-addons) - Essential cluster add-ons


# Managing Nodegroups

Node groups are collections of worker nodes that run your containerized applications. This guide covers creating, scaling, and managing node groups in your Kubernetes cluster.

## What is a Node Group?

A node group is a set of Kubernetes worker nodes with identical configuration:

* **Instance Type**: CPU, memory, and other hardware specifications
* **Disk Size**: Storage capacity for each node
* **Scaling**: Minimum, maximum, and desired node count
* **Labels**: Key-value pairs for workload scheduling
* **Taints**: Restrictions on which pods can be scheduled
* **Network**: Subnet configuration

## Why Node Groups Matter

Node groups allow you to:

* **Separate Workloads**: System services vs. applications
* **Optimize Resources**: Different instance types for different needs
* **Control Costs**: Scale and size appropriately
* **Isolate Workloads**: Use taints and labels for pod placement

## Critical: Untainted Node Groups

{% hint style="danger" %}
Always create at least 1–2 nodes without taints before creating any specialized node groups.

Essential cluster components require untainted nodes:

* CoreDNS: DNS resolution for services and pods
* Cilium (or your CNI): Pod networking

Without untainted nodes:

* Essential add-ons cannot be scheduled
* Cluster will not function properly
* Pods cannot start or communicate
* DNS resolution will fail
  {% endhint %}

Recommended First Node Group:

```yaml
Name: general-nodes
Purpose: Run cluster components and general workloads
Instance Type: 2vcpu-4gb or larger
Scaling:
  Min Size: 1
  Max Size: 3
  Desired Size: 2
Taints: None (this is critical!)
Labels:
  workload-type: general
```

## Creating a Node Group

### Node Group Configuration

When creating a node group, you'll need to configure the following settings.

### Basic Settings

#### Node Group Name

Choose a descriptive name.

Naming Rules:

* Maximum 100 characters
* Lowercase alphanumeric characters, hyphens (-), and dots (.)
* Must start and end with alphanumeric characters
* No consecutive dots (..) or hyphens (--)

Examples:

* ✅ Good: `general-nodes`, `app-workers`, `gpu-nodes-prod`
* ❌ Bad: `ng1`, `nodes`, `test`

#### Instance Type (Flavor)

Select the compute resources for your nodes.

Available Instance Types:

```yaml
Small:
  - 2vcpu-4gb: Good for light workloads, development
  - 2vcpu-8gb: Development, small applications

Medium:
  - 4vcpu-8gb: Standard applications
  - 4vcpu-16gb: Memory-intensive applications

Large:
  - 8vcpu-16gb: Production workloads
  - 8vcpu-32gb: Large applications, databases
```

Choosing Instance Type:

```
General Nodes:
  ├─ Minimum: 2vcpu-4gb
  └─ Recommended: 2vcpu-8gb

Application Nodes:
  ├─ Development: 2vcpu-4gb to 4vcpu-8gb
  ├─ Production: 4vcpu-8gb to 8vcpu-16gb
  └─ High Performance: 8vcpu-16gb or larger

Specialized Nodes:
  ├─ Memory-intensive: Choose high memory ratio
  ├─ CPU-intensive: Choose high CPU count
  └─ GPU workloads: GPU-enabled instances
```

### Disk Configuration

Configure root disk size for each node.

Disk Size Examples:

```
General Purpose:
  - Min Size: 1
  - Max Size: 5
  - Disk: 80-100 GB

Application Nodes:
  - Min Size: 2
  - Max Size: 10
  - Disk: 100-200 GB

Data Processing:
  - Min Size: 1
  - Max Size: 5
  - Disk: 200-500 GB
```

* **Minimum**: 50 GB
* **Default**: 80 GB (if not specified)
* **Recommended**:
  * General nodes: 80-100 GB
  * Application nodes: 100-200 GB
  * Image-heavy workloads: 200+ GB

What uses disk space?

```
Node Disk Usage:
├─ Operating system: ~10 GB
├─ Container images: 20-50 GB (varies)
├─ Container logs: 5-10 GB
├─ kubelet working directory: 10-20 GB
└─ Available for EmptyDir volumes: Remaining space
```

Planning Disk Size:

```yaml
# Small node group (minimal images)
diskSize: 80

# Standard node group (moderate images)
diskSize: 100

# Large images or many containers
diskSize: 200

# Machine learning / data processing
diskSize: 500
```

### Scaling Configuration

Define how your node group scales.

#### Scaling Configuration

**Min Size**: Minimum number of nodes (always running)

* Cannot be less than 0
* Should be at least 1 for production
* Can be 0 for dev/test environments (but node group creation needs at least 1)

**Max Size**: Maximum number of nodes (limit for scaling)

* Must be >= Min Size
* Set based on maximum expected load
* Consider account quota limits

**Desired Size**: Target number of nodes (current goal)

* Must be between Min Size and Max Size
* Can be adjusted later
* Cluster autoscaler can modify this

Scaling Examples:

```yaml
# General nodes (stable, always running)
minSize: 2
maxSize: 3
desiredSize: 2

# Application nodes (can scale)
minSize: 2
maxSize: 10
desiredSize: 3

# Batch processing (scale to zero when idle)
minSize: 0
maxSize: 20
desiredSize: 0  # Can't create with 0, will scale down later

# High availability production
minSize: 3
maxSize: 10
desiredSize: 5
```

Validation Rules:

```
minSize ≤ desiredSize ≤ maxSize
All values must be non-negative integers
```

### Network Configuration

#### Subnet Selection

**Subnet KRN** (Required):

* Select the subnet where node network interfaces will be created
* Must be in the same VPC as the cluster
* Ensure sufficient IP addresses available

IP Address Planning:

```
Each node requires:
├─ 1 IP for primary network interface
└─ Additional IPs for pods (from Pod CIDR, not subnet)

Example:
10 nodes in subnet 10.0.1.0/24 (254 usable IPs):
├─ 10 IPs for nodes
├─ 244 IPs remaining
└─ Plan for growth and other resources
```

### Labels Configuration (Optional)

Labels are key-value pairs used for pod scheduling.

Common Label Patterns:

```yaml
# Node role identification
node-role: system
node-role: application
node-role: database

# Environment separation
environment: production
environment: staging

# Workload type
workload-type: compute-intensive
workload-type: memory-intensive
workload-type: gpu

# Team or project
team: platform
team: data-science
project: web-app
```

Usage Example:

```yaml
# In node group configuration
labels:
  node-role: application
  environment: production
  team: platform
```

```yaml
# In pod specification
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  nodeSelector:
    node-role: application
    environment: production
```

### Taints Configuration (Optional)

Taints restrict which pods can be scheduled on nodes. Pods must have matching tolerations.

Taint Structure:

```yaml
key: taint-key
value: taint-value
effect: NoSchedule|PreferNoSchedule|NoExecute
```

Taint Effects:

* NoSchedule:
  * Hard requirement
  * Pods without toleration will NOT be scheduled
  * Existing pods not affected
* PreferNoSchedule:
  * Soft requirement
  * System tries to avoid scheduling
  * Will schedule if no other option
* NoExecute:
  * Evicts running pods without toleration
  * Prevents new pods from being scheduled
  * Use with caution!

Common Taint Scenarios:

Scenario: Dedicated GPU Nodes

```yaml
# Node group taint
key: workload
value: gpu
effect: NoSchedule

# Pod toleration (only GPU workloads)
tolerations:
- key: workload
  operator: Equal
  value: gpu
  effect: NoSchedule
```

Scenario: High-Priority Production Nodes

```yaml
# Node group taint
key: environment
value: production
effect: NoSchedule

# Pod toleration (production pods only)
tolerations:
- key: environment
  operator: Equal
  value: production
  effect: NoSchedule
```

Scenario: General Purpose Nodes (NO TAINTS!)

```yaml
# General node group
taints: []  # Empty - no taints

# Allows:
├─ CoreDNS to schedule
├─ Cilium to schedule
└─ All other pods without tolerations
```

{% hint style="warning" %}
DO NOT add taints to your first node group!

* ❌ If all nodes are tainted, system pods cannot schedule and the cluster becomes non-functional.
* ✅ Ensure at least 1–2 nodes without taints so system pods can schedule and the cluster remains functional.
  {% endhint %}

### Remote Access Configuration (Optional)

Enable SSH access to nodes for debugging:

SSH Key Selection:

* Choose from your existing SSH keys
* Required for SSH access to nodes
* Recommended for troubleshooting

Security Groups:

* Select security groups for SSH access
* Restrict SSH access to specific IPs/networks
* Follow security best practices

When to Enable:

* ✅ Development/testing environments
* ✅ Troubleshooting scenarios
* ⚠️ Production (only if necessary with strict security)

### Node Repair Configuration (Optional)

Automatic node health monitoring and repair:

Node Repair Configuration:

```yaml
enabled: true  # Enable automatic node repair
```

What it does:

* Monitors node health
* Detects failed or unhealthy nodes
* Automatically replaces unhealthy nodes
* Helps maintain cluster availability

When to enable:

* ✅ Production clusters (recommended)
* ✅ Critical workloads
* ✅ Long-running clusters

When to disable:

* Development environments
* Short-lived clusters
* Manual node management preference

### Creating the Node Group

After configuring all settings:

* Name and instance type
* Scaling configuration
* Labels and taints
* Network settings

Verification Checklist:

* [ ] For first node group: NO taints configured
* [ ] Scaling values are valid (min ≤ desired ≤ max)
* [ ] Subnet has sufficient IPs
* [ ] Instance type matches workload needs

Submit the node group configuration to begin creation.

## Node Group Lifecycle

### Creation Process

CREATING → SCALINGUP → RUNNING

Timeline:

* Initial setup: 1–2 minutes
* Node provisioning: 3–5 minutes per node
* Kubernetes join: 1–2 minutes per node
* Total: 5–10 minutes for 2–3 nodes

What's happening:

{% stepper %}
{% step %}

### OpenStack instance creation

OpenStack instances are created for the nodes.
{% endstep %}

{% step %}

### Network configuration

Network interfaces and security settings are applied.
{% endstep %}

{% step %}

### Kubernetes components installation

Kubernetes components are installed on the new nodes.
{% endstep %}

{% step %}

### Nodes join the cluster

Nodes join the cluster and become Ready once initialized.
{% endstep %}
{% endstepper %}

Monitoring Creation:

```bash
# Monitor node group status
# Status: CREATING → SCALINGUP → RUNNING

# Watch nodes joining cluster
kubectl get nodes -w

# Check node group pods
kubectl get pods -A -o wide
```

### Node Group States

* CREATING: Initial setup in progress
* SCALINGUP: Adding nodes
* RUNNING: Operational and healthy
* SCALINGDOWN: Removing nodes
* UPDATING: Configuration or version update
* FAILED: Operation failed (check error message)
* PENDING\_DELETE: Deletion initiated
* DELETING: Removal in progress

## Scaling Node Groups

### Manual Scaling

Update desired size to scale your node group:

Configuration Update:

* Modify the Desired Size parameter
* Submit the configuration change

Scaling Up (Desired > Current):

```
RUNNING → SCALINGUP → RUNNING
Timeline: 3–5 minutes per new node
```

Scaling Down (Desired < Current):

```
RUNNING → SCALINGDOWN → RUNNING
Timeline: 2–4 minutes per removed node
```

Important: Nodes are drained before removal. Ensure:

* [ ] Workloads can be rescheduled
* [ ] No PodDisruptionBudgets blocking
* [ ] No local data will be lost

### Automatic Scaling

If Cluster Autoscaler add-on is installed:

How it works:

1. Scale Up: Pods cannot be scheduled → Add nodes
2. Scale Down: Nodes underutilized → Remove nodes

Configuration:

* Autoscaler respects min/max size
* Can modify desired size automatically
* Checks for un-schedulable pods
* Monitors node utilization

Scaling Behavior:

```
Pod pending (no resources):
├─ Cluster Autoscaler detects
├─ Checks: current < max size
├─ Increases desired size
└─ New nodes provisioned

Node underutilized (< 50% for 10min):
├─ Cluster Autoscaler detects
├─ Checks: current > min size
├─ Drains node safely
└─ Decreases desired size
```

## Updating Node Groups

### Update Configuration

Update scaling or repair settings for your node group.

Updatable Settings:

* ✅ Min size
* ✅ Max size
* ✅ Desired size
* ✅ Node repair configuration

What cannot be updated:

* ❌ Instance type (create new node group)
* ❌ Disk size (create new node group)
* ❌ Labels (recreate nodes)
* ❌ Taints (recreate nodes)
* ❌ Subnet (create new node group)

### Update Kubernetes Version

Keep node group version aligned with cluster.

Rolling update process:

{% stepper %}
{% step %}

### New node creation

New node is created with the new Kubernetes version.
{% endstep %}

{% step %}

### New node joins

New node joins the cluster and becomes Ready.
{% endstep %}

{% step %}

### Cordoning old node

Old node is cordoned (no new pods scheduled).
{% endstep %}

{% step %}

### Draining old node

Old node is drained and pods are rescheduled.
{% endstep %}

{% step %}

### Deleting old node

Old node is deleted.
{% endstep %}

{% step %}

### Repeat

Repeat for the next node until all are updated.
{% endstep %}
{% endstepper %}

Timeline: \~5–10 minutes per node

Important Considerations:

* [ ] Ensure workloads can be rescheduled
* [ ] Check PodDisruptionBudgets allow rolling update
* [ ] Verify sufficient capacity during update
* [ ] Monitor application health during update

## Node Group Best Practices

### ✅ Do's

* Create Untainted Nodes First
  * Start with nodes that have NO taints
  * Ensure essential components can schedule
  * Wait for nodes to be Ready before creating tainted nodes
* Separate Workloads
  * System components: Dedicated untainted nodes
  * Applications: Separate node groups by purpose
  * Specialized: GPU, high-memory, etc.
* Plan Capacity
  * Set appropriate min/max for each node group
  * Consider peak load in max size
  * Allow headroom for updates
* Use Meaningful Labels
  * Label nodes by purpose, environment, team
  * Document label schema
  * Use labels for pod scheduling
* Configure Node Repair
  * Enable for production node groups
  * Improves reliability
  * Reduces manual intervention
* Right-Size Instances
  * Match instance type to workload
  * Don't over-provision
  * Monitor and adjust

### ❌ Don'ts

* Don't Taint All Nodes
  * Always have untainted nodes for essential components
  * Cilium and CoreDNS need untainted nodes
* Don't Under-Size Nodes
  * Minimum 2vcpu-4gb for general workloads
  * Cluster components need resources
* Don't Forget Disk Space
  * Plan for images, logs, temp storage
  * Monitor disk usage
  * Increase if nodes run out of space
* Don't Set Min = Max
  * Allow scaling flexibility
  * Use autoscaler for efficiency
  * Unless fixed size is required
* Don't Block Draining
  * Avoid aggressive PodDisruptionBudgets
  * Plan for node updates
  * Allow graceful termination

## Common Node Group Patterns

### Pattern: Standard Three-Tier

Node Group Planning Example:

```yaml
# General nodes - always running
general-nodes:
  instance: 4vcpu-8gb
  min: 2, max: 5, desired: 2
  taints: none

# Application nodes - scalable
app-nodes:
  instanceType: 4vcpu-16gb
  diskSize: 150
  minSize: 3
  maxSize: 10
  desiredSize: 5
  taints: []
  labels:
    node-role: application
    workload-type: general

# Batch processing - can scale to zero
batch-nodes:
  instanceType: 8vcpu-32gb
  diskSize: 200
  minSize: 0
  maxSize: 20
  desiredSize: 2
  taints:
  - key: workload
    value: batch
    effect: NoSchedule
  labels:
    node-role: batch
    workload-type: batch-processing
```

### Pattern: Environment Separation

```yaml
# Production - highly available
prod-nodes:
  instanceType: 8vcpu-16gb
  diskSize: 200
  minSize: 5
  maxSize: 20
  desiredSize: 10
  taints:
  - key: environment
    value: production
    effect: NoSchedule
  labels:
    environment: production
    tier: application

# Staging - moderate resources
staging-nodes:
  instanceType: 4vcpu-8gb
  diskSize: 100
  minSize: 2
  maxSize: 5
  desiredSize: 3
  taints:
  - key: environment
    value: staging
    effect: NoSchedule
  labels:
    environment: staging
    tier: application
```

## Troubleshooting Node Groups

<details>

<summary>Node Group Stuck in CREATING</summary>

Symptoms:

* Node group status remains CREATING
* No nodes appearing in cluster

Possible Causes:

* Cluster not in PROVISIONED state
* Insufficient subnet IPs
* Invalid configuration
* OpenStack quota exceeded

Solution:

```bash
# Check cluster status
Cluster status should be PROVISIONED

# Check subnet has available IPs

# Verify subnet capacity in VPC service

# Check account quota

# Verify instance quota in OpenStack

# Review error message

# Check node group details for specific error
```

</details>

<details>

<summary>Nodes Not Reaching Ready State</summary>

Symptoms:

* Node group status SCALINGUP
* Nodes in NotReady state

Possible Causes:

* CNI not installed
* All nodes have taints (system pods can't schedule)
* Network connectivity issues

Solution:

```bash
# Check node status
kubectl get nodes

# Check why NotReady
kubectl describe node <node-name>

# Check CNI pods
kubectl get pods -n kube-system -l k8s-app=cilium

# Ensure you have untainted nodes

# System pods must be able to schedule
```

</details>

<details>

<summary>Scaling Down Stuck</summary>

Symptoms:

* Node group stuck in SCALINGDOWN
* Desired size < current size but nodes not removed

Possible Causes:

* PodDisruptionBudget preventing drain
* Pods with local storage
* Pods without controller (bare pods)

Solution:

```bash
# Check what's preventing drain
kubectl get pods -A --field-selector spec.nodeName=<node-name>

# Check PodDisruptionBudgets
kubectl get pdb -A

# Manually drain if needed (understand impact!)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
```

</details>

## Additional Resources

* [Installing Add-ons](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/installing-addons) - Install CNI and other essential add-ons
* [Creating Cluster Guide](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/creating-cluster) - Cluster setup process
* [Troubleshooting Guide](broken://pages/ddb69b507463367afd9c067d63cb5341a80fa3e8) - Common issues and solutions


# Installing Addons

Add-ons extend your Kubernetes cluster with additional functionality. This guide covers installing and managing add-ons in the Krutrim Kubernetes Service.

## What are Add-ons?

Add-ons are additional components that provide essential services or extended functionality to your Kubernetes cluster:

* **Core Services**: DNS (CoreDNS) for service discovery
* **Networking**: CNI plugins for pod networking (Cilium, kube-proxy)
* **Storage**: CSI drivers for persistent storage
* **Monitoring**: Metrics collection and observability
* **Autoscaling**: Automatic node and pod scaling

Note: All add-ons, including CoreDNS, must be manually installed after cluster creation.

## Critical: CNI Installation

### What is CNI?

CNI (Container Network Interface) is required for pod-to-pod communication in your cluster. Without a CNI, your cluster pods cannot communicate.

### Kube-proxy vs. Cilium

You have two primary networking options:

#### Option 1: Cilium (Recommended) ⭐

What is Cilium?

* Modern eBPF-based CNI solution
* High-performance networking
* Built-in network security and observability
* Deployed via Helm chart

Important: Do NOT Install Kube-proxy with Cilium

```
❌ INCORRECT Configuration:
   Install kube-proxy ➜ Install Cilium ➜ Networking issues

✅ CORRECT Configuration:
   Install Cilium ONLY ➜ Full networking functionality
```

Why?

* Cilium replaces kube-proxy functionality using eBPF
* Running both can cause conflicts and networking issues
* Cilium provides better performance and features

When to Use Cilium:

* ✅ New clusters
* ✅ Production workloads
* ✅ Need for network security policies
* ✅ High-performance requirements

#### Option 2: Kube-proxy + Your Own CNI

What is Kube-proxy?

* Traditional Kubernetes networking component
* Provides Service load balancing
* Required if you want to use your own CNI solution

When to Use This Option:

* ✅ Need specific CNI solution (Calico, Flannel, etc.)
* ✅ Have existing expertise with particular CNI
* ✅ Require specific features from other CNI providers

Important: Cilium Add-on May Not Work with Kube-proxy

```
If you install kube-proxy:
├─ You can install your own CNI solution ✅
├─ DO NOT install Cilium add-on ❌
└─ Cilium is designed to work without kube-proxy
```

### CNI Installation Decision Flow

```
┌─────────────────────────────────────────┐
│   Do you need a specific CNI solution?  │
└─────────────┬──────────────┬────────────┘
              │              │
        ┌─────▼──────┐  ┌───▼──────┐
        │     NO     │  │   YES    │
        └─────┬──────┘  └───┬──────┘
              │             │
              │             │
    ┌─────────▼────────┐    │
    │  Install Cilium  │    │
    │   (Recommended)  │    │
    └─────────┬────────┘    │
              │             │
    ┌─────────▼────────┐    │
    │  Do NOT install  │    │
    │   kube-proxy     │    │
    └──────────────────┘    │
                            │
              ┌─────────────▼────────────┐
              │  Install kube-proxy first│
              └─────────────┬────────────┘
                            │
              ┌─────────────▼────────────┐
              │ Install your own CNI     │
              │ (Calico, Flannel, etc.)  │
              └──────────────────────────┘
```

## Available Add-ons

The Krutrim Kubernetes Service provides several add-ons to extend cluster functionality.

### Core Add-ons

#### CoreDNS (Recommended)

Description: DNS service for Kubernetes cluster

Features:

* Service discovery and DNS resolution
* Pod-to-service name resolution
* Essential for cluster functionality

Installation:

```
Add-on: CoreDNS
Version: Default or specific version
Configuration: Default settings

Important: Required for service discovery in your cluster
```

Verification:

```bash
# Check CoreDNS pods are running
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Test DNS resolution
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
```

### Networking Add-ons

#### Cilium (Recommended)

Description: eBPF-based networking and security solution

Features:

* Pod networking and connectivity
* Service load balancing (replaces kube-proxy)
* Network security policies
* Network observability
* High performance with eBPF

Installation:

```
Add-on: Cilium
Version: Default or specific version
Configuration: Default settings

Important: DO NOT install kube-proxy when using Cilium
```

Verification:

```bash
# Check Cilium pods are running
kubectl get pods -n kube-system -l k8s-app=cilium

# Verify Cilium status
kubectl exec -n kube-system -ti cilium-xxx -- cilium status
```

#### Kube-proxy

Description: Traditional Kubernetes network proxy

Features:

* Service load balancing
* iptables-based networking
* Standard Kubernetes component

When to Install:

* Only if you plan to use your own CNI solution
* Do NOT install if using Cilium add-on

Installation:

```
Add-on: kube-proxy
Version: Default or specific version
Configuration: Default settings

Important: Install kube-proxy ONLY if using your own CNI solution
Then install your preferred CNI separately using kubectl/helm
```

### Storage Add-ons

#### CSI

Description: Container Storage Interface driver for persistent storage

Features:

* Persistent Volume (PV) support
* Dynamic volume provisioning
* Storage class management
* Integration with Krutrim Cloud storage

Important: Default Storage Class

```
Storage class is ONLY available if CSI add-on is enabled.

Without CSI:
├─ No default storage class
├─ Cannot create PersistentVolumeClaims
└─ No dynamic volume provisioning

With CSI:
├─ Default storage class available ✅
├─ Can create PersistentVolumeClaims ✅
└─ Dynamic volume provisioning ✅
```

Installation:

```
Add-on: CSI
Version: Default or specific version
Configuration: Default settings
```

Verification:

```bash
# Check storage class is available
kubectl get storageclass

# Expected output:
NAME                 PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE
csi-cinder-sc-qos-delete (default) cinder.csi.openstack.org      Delete          Immediate

# Verify CSI pods
kubectl get pods -n kube-system | grep csi
```

Usage Example:

```yaml
# Create a PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  # storageClassName: csi-cinder-sc-qos-retain  # Optional, uses default if omitted
```

### Other Add-ons

#### Cluster Autoscaler

Description: Automatically adjusts node group sizes based on resource demands

Features:

* Automatic node scaling up/down
* Cost optimization
* Resource efficiency

When to Use:

* Variable workload patterns
* Cost-sensitive environments
* Need for automatic capacity management

#### Metrics Server

Description: Collects resource metrics from kubelets

Features:

* CPU and memory metrics
* Enables `kubectl top` commands
* Required for Horizontal Pod Autoscaler (HPA)

When to Use:

* Need resource monitoring
* Using Horizontal Pod Autoscaler
* Want to track resource usage with `kubectl top`

## Installing Add-ons: Process Overview

### Installation Steps

{% stepper %}
{% step %}

### Select Add-on

* Choose the add-on you want to install
* Review add-on description and requirements
  {% endstep %}

{% step %}

### Configure Add-on

Version Selection:

* Default Version: Recommended for most cases (automatically selected)
* Specific Version: Choose if you need a particular version
* Compatibility: System automatically shows compatible versions for your cluster

Add-on Configuration:

* Most add-ons use sensible defaults
* Advanced configuration typically not needed
* System automatically selects compatible versions
  {% endstep %}

{% step %}

### Install and Monitor

* Submit the add-on installation
* Typical installation time: 2 minutes
  {% endstep %}

{% step %}

### Verify Installation

After installation completes:

```bash
# List add-ons
kubectl get pods -A

# Check specific add-on (example: Cilium)
kubectl get pods -n kube-system -l k8s-app=cilium

# Verify add-on is functioning
kubectl describe pod <pod-name> -n kube-system
```

{% endstep %}
{% endstepper %}

## Installation Order Best Practices

{% stepper %}
{% step %}

### Create cluster

* Wait for PROVISIONED status
  {% endstep %}

{% step %}

### Create node groups

* At least 1–2 nodes without taints
* Wait for nodes to be Ready
  {% endstep %}

{% step %}

### Install CNI (CHOOSE ONE)

* Option A: Cilium ONLY (no kube-proxy) ⭐
* Option B: kube-proxy → Your own CNI
  {% endstep %}

{% step %}

### Verify cluster functionality

* Check all nodes are Ready
* Check all system pods are Running
  {% endstep %}

{% step %}

### Install storage (if needed)

* CSI Node Plugin
  {% endstep %}

{% step %}

### Install optional add-ons

* Cluster Autoscaler
* Metrics Server
* Others as needed
  {% endstep %}
  {% endstepper %}

Why This Order Matters:

```
Cluster → Nodes → CNI → Storage → Others
    ↓        ↓       ↓       ↓        ↓
Required  Required  Required Optional Optional
           for CNI   for     for PVs   for
           to work   system           features
```

## Managing Add-ons

### Viewing Installed Add-ons

View list of installed add-ons with:

* Add-on name
* Version
* Status
* Installation date

## Common Add-on Scenarios

### Scenario 1: New Production Cluster

Recommended Add-ons:

* CoreDNS
* Cilium (without kube-proxy)
* CSI Node Plugin
* Metrics Server
* Cluster Autoscaler (if variable load)

### Scenario 2: Development/Testing Cluster

Minimal Add-ons:

* CoreDNS
* Cilium (without kube-proxy)
* CSI Node Plugin (if testing with PVs)

Installation Order:

* CoreDNS → Wait complete
* Cilium → Verify networking
* CSI Node Plugin (optional, only if needed)

### Scenario 3: Using Custom CNI

Required Add-ons:

* CoreDNS
* Kube-proxy
* Your CNI (installed separately)
* CSI Node Plugin (if needed)

Installation Order:

* CoreDNS → Wait complete
* Kube-proxy → Wait complete
* Install your CNI using kubectl/helm
* Verify all nodes Ready
* CSI Node Plugin if needed

## Troubleshooting Add-on Installation

<details>

<summary>Add-on Stuck in CREATING</summary>

Possible Causes:

* Nodes not ready
* Insufficient resources
* Network connectivity issues

Solution:

```bash
# Check node status
kubectl get nodes

# Check add-on pods
kubectl get pods -A

# Describe failing pod
kubectl describe pod <pod-name> -n <namespace>
```

</details>

<details>

<summary>Add-on Installation Failed</summary>

Possible Causes:

* Version incompatibility
* Conflicting add-ons
* Resource constraints

Solution:

1. Check add-on status in UI
2. Review error messages
3. Verify cluster has sufficient resources
4. Remove add-on and try compatible version

</details>

<details>

<summary>Cilium Not Working</summary>

Possible Causes:

* Kube-proxy also installed (conflict)
* Nodes not ready
* Insufficient permissions

Solution:

```bash
# Check if kube-proxy is running
kubectl get pods -n kube-system -l k8s-app=kube-proxy

# If kube-proxy exists, it conflicts with Cilium

# Remove one or the other

# Check Cilium status
kubectl exec -n kube-system -ti cilium-xxx -- cilium status

# View Cilium logs
kubectl logs -n kube-system -l k8s-app=cilium
```

</details>

<details>

<summary>Storage Class Not Available</summary>

Possible Causes:

* CSI Node Plugin add-on not installed
* CSI pods not running

Solution:

```bash
# Check CSI add-on status
kubectl get pods -n kube-system | grep csi

# Install CSI Node Plugin if missing

# Verify storage class
kubectl get storageclass
```

</details>

## Add-on Best Practices

### ✅ Do's

1. Install CoreDNS First: Required for service discovery before other add-ons
2. Install CNI Early: Pod networking is essential for cluster functionality
3. Choose One CNI Strategy: Either Cilium OR kube-proxy + custom CNI
4. Verify After Installation: Check pod status after each add-on
5. Install CSI Node Plugin for Storage: If you need persistent volumes

### ❌ Don'ts

1. Don't Skip CoreDNS: Service discovery won't work without it
2. Don't Install Cilium with Kube-proxy: They conflict
3. Don't Skip Verification: Always verify add-on is working
4. Don't Install Multiple CNIs: Choose one networking solution

## Additional Resources

* [Configure Storage](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/storage-configuration) - Use your CSI storage class
* [Create Load Balancers](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/load-balancers) - Expose services with OCCM
* [Best Practices](broken://pages/8f36a824bf0b8e37d537731c3a9044d23842a672) - Cluster optimization guidelines
* [Troubleshooting Guide](broken://pages/ddb69b507463367afd9c067d63cb5341a80fa3e8) - Common issues and solutions


# Network Configuration

Proper network configuration is crucial for your Kubernetes cluster. This guide explains the key networking concepts and how to configure them correctly.

## Network Configuration Components

When creating a cluster, configure these three main network elements:

{% stepper %}
{% step %}

### Pod CIDR (Pod IP Address Range)

The Pod CIDR defines the IP address range used by pods running in your cluster.

#### What is Pod CIDR?

* Definition: The IP address range assigned to pods in your cluster
* Default: `192.168.0.0/16` (if not specified)
* Format: Must be a valid IPv4 CIDR notation

#### Important Considerations

{% hint style="warning" %}
The range `172.24.0.0/13` is reserved for system use and cannot be used for Pod CIDR.
{% endhint %}

* Allowed CIDR Ranges:
  * `10.0.0.0/8` - Class A private network
  * `172.16.0.0/12` - Class B private network (excluding reserved `172.24.0.0/13`)
  * `192.168.0.0/16` - Class C private network
* No overlap with Node Subnet: Your Pod CIDR **must not overlap** with the VPC subnet(s) where your nodes are deployed. Nodes use IPs from the VPC subnet, and these ranges must be separate from Pod and Service CIDRs.
* Subnet Allocation: Each node receives a /24 subnet from your Pod CIDR for its pods.

Capacity planning example:

```
If you configure Pod CIDR as 192.168.0.0/16:
- Total IP addresses available: 65,536
- Each node gets a /24 subnet: 256 IPs per node
- Maximum nodes you can create: 256 nodes
- Each node can run up to 256 pods (minus system overhead)
```

Planning formula:

```
Pod CIDR: X.X.X.X/N
Node Subnet: /24 (fixed)
Maximum Nodes = 2^(24-N)

Examples:
- /16 Pod CIDR = 2^(24-16) = 256 nodes
- /17 Pod CIDR = 2^(24-17) = 128 nodes
- /18 Pod CIDR = 2^(24-18) = 64 nodes
- /20 Pod CIDR = 2^(24-20) = 16 nodes
```

#### Best Practices for Pod CIDR

* Small Clusters (< 10 nodes):
  * Use `/20` or larger: `192.168.0.0/20` — Provides 16 nodes × 256 pods/node
* Medium Clusters (10-50 nodes):
  * Use `/18`: `192.168.0.0/18` — Provides 64 nodes × 256 pods/node
* Large Clusters (50-256 nodes):
  * Use `/16`: `192.168.0.0/16` — Provides 256 nodes × 256 pods/node
* Very Large Clusters (> 256 nodes):
  * Use larger ranges like `/15` or `/14`; plan carefully

{% hint style="danger" %}
Important: Once set, the Pod CIDR cannot be changed without recreating the cluster. Plan accordingly!
{% endhint %}
{% endstep %}

{% step %}

### Service CIDR (Service IP Address Range)

The Service CIDR defines the IP address range used by Kubernetes Services.

#### What is Service CIDR?

* Definition: The IP address range assigned to Kubernetes Services (ClusterIP, NodePort, LoadBalancer)
* Default: `10.100.0.0/16` (if not specified)
* Format: Must be a valid IPv4 CIDR notation

#### Important Considerations

{% hint style="warning" %}
The range `172.24.0.0/13` is reserved for system use and cannot be used for Service CIDR.
{% endhint %}

* Allowed CIDR Ranges:
  * `10.0.0.0/8` - Class A private network
  * `172.16.0.0/12` - Class B private network (excluding reserved `172.24.0.0/13`)
  * `192.168.0.0/16` - Class C private network
* No overlap with Node Subnet: Your Service CIDR **must not overlap** with the VPC subnet(s) where your nodes are deployed.
* Usage Pattern:
  * Each Service consumes one IP address
  * IP addresses are assigned sequentially
  * First IP (e.g., `10.100.0.1`) is reserved for `kubernetes.default` service

Capacity planning example:

```
If you configure Service CIDR as 10.100.0.0/16:
- Total IP addresses available: 65,536
- Maximum Services: ~65,000 (accounting for reserved IPs)
```

#### Best Practices for Service CIDR

* Typical Clusters:
  * Use `/16`: `10.100.0.0/16` — 65,536 service IPs
* Small Deployments:
  * Use `/20`: `10.100.0.0/20` — 4,096 service IPs

Separation example:

* Good: Pod CIDR: `192.168.0.0/16`, Service CIDR: `10.100.0.0/16`, Node Subnet: `172.16.1.0/24`
* Bad: Overlapping ranges between any of these networks
  {% endstep %}

{% step %}

### VPC and Subnet Configuration

Your cluster runs within your VPC (Virtual Private Cloud) infrastructure.

#### VPC KRN (Required)

* What it is: Reference to your VPC where the cluster will be deployed
* Format: `krn:vpc:region:account:user:vpc:vpc-id`
* Purpose: Defines the network boundary for your cluster

#### Subnet KRN (Required)

* What it is: Reference to the subnet(s) where cluster resources will be deployed
* Format: `krn:vpc:region:account:user:subnet:subnet-id`
* Important: The subnet specified here is used when creating LoadBalancer services

LoadBalancer IP allocation:

```
When you create a Kubernetes Service of type LoadBalancer:
- The LoadBalancer is created in the subnet you specified in Subnet KRN
- One IP address is allocated from that subnet for the LoadBalancer
- This IP is taken from your subnet's available IP pool
```

Example:

```yaml
VPC: 10.0.0.0/16
Subnet for Cluster: 10.0.1.0/24 (254 usable IPs)

If you create 10 LoadBalancer services:
- 10 IPs will be used from the 10.0.1.0/24 subnet
- Remaining IPs: 244 available for LoadBalancers or other resources
```

#### Best Practices for VPC/Subnet

* Subnet Size: Ensure your subnet has enough IPs for:
  * Node network interfaces
  * LoadBalancer services
  * Other cloud resources\
    Recommended: Use at least a /24 subnet (256 IPs)
* Dedicated Subnets: Consider using dedicated subnets for:
  * Cluster nodes
  * LoadBalancers
  * Application-specific resources
* IP Planning example:

```
- Subnet for nodes: 10.0.1.0/24 (256 IPs)
- Subnet for LoadBalancers: 10.0.2.0/24 (256 IPs)
- Reserve IPs for future growth
```

{% endstep %}
{% endstepper %}

## Network Configuration Examples

### Example 1: Small Development Cluster

```
Cluster Name: dev-cluster
Pod CIDR: 192.168.0.0/20 (supports up to 16 nodes)
Service CIDR: 10.100.0.0/20 (4,096 services)
VPC KRN: krn:vpc:region:account:user:vpc:dev-vpc
Subnet KRN: krn:vpc:region:account:user:subnet:dev-subnet-1
Node Subnet (in VPC): 172.16.1.0/24 (for node IPs)

Note: Pod CIDR (192.168.x.x), Service CIDR (10.100.x.x), and Node Subnet (172.16.x.x) 
      are all in different ranges with no overlap.

Use Case:
- 5-10 nodes
- Development and testing
- Limited LoadBalancers
```

### Example 2: Medium Production Cluster

```
Cluster Name: prod-cluster
Pod CIDR: 192.168.0.0/18 (supports up to 64 nodes)
Service CIDR: 10.100.0.0/16 (65,536 services)
VPC KRN: krn:vpc:region:account:user:vpc:prod-vpc
Subnet KRN: krn:vpc:region:account:user:subnet:prod-subnet-1
Node Subnet (in VPC): 172.16.0.0/24 (for node IPs)

Note: All three ranges are separate and non-overlapping.

Use Case:
- 20-50 nodes
- Production workloads
- Multiple services with LoadBalancers
```

### Example 3: Large Enterprise Cluster

```
Cluster Name: enterprise-cluster
Pod CIDR: 192.168.0.0/16 (supports up to 256 nodes)
Service CIDR: 10.100.0.0/16 (65,536 services)
VPC KRN: krn:vpc:region:account:user:vpc:enterprise-vpc
Subnet KRN: krn:vpc:region:account:user:subnet:enterprise-subnet-1
Node Subnet (in VPC): 172.16.0.0/23 (for node IPs - larger for more nodes)

Note: Enterprise setup with separate IP ranges for each network layer.

Use Case:
- 100+ nodes
- Large-scale production
- Microservices architecture with many services
```

## Network Configuration Checklist

Before creating your cluster, verify:

* [ ] Pod CIDR is sized appropriately for your planned node count
* [ ] Service CIDR is large enough for your expected number of services
* [ ] No overlap between Pod CIDR and Service CIDR
* [ ] No overlap between Pod CIDR and Node Subnet (VPC subnet)
* [ ] No overlap between Service CIDR and Node Subnet (VPC subnet)
* [ ] Reserved ranges avoided: Not using `172.24.0.0/13`
* [ ] Using allowed private ranges: `10.0.0.0/8`, `172.16.0.0/12` (excluding reserved), or `192.168.0.0/16`
* [ ] VPC exists and is accessible
* [ ] Subnet has sufficient IPs for nodes and LoadBalancers
* [ ] Subnet is in the correct VPC
* [ ] Network ranges don't conflict with other infrastructure

## Common Mistakes to Avoid

### ❌ Pod CIDR Too Small

```
Problem: Pod CIDR 192.168.0.0/24 (only 1 node possible)
Solution: Use at least /20 or larger
```

### ❌ Using Reserved Range

```
Problem: Pod CIDR 172.24.0.0/16 (reserved range)
Solution: Use 192.168.0.0/16 or 10.x.x.x ranges
```

### ❌ Overlapping CIDRs

```
Problem 1: Pod and Service CIDR overlap
  Pod CIDR: 10.0.0.0/16
  Service CIDR: 10.0.0.0/16
Solution: Use separate ranges (e.g., Pod: 192.168.0.0/16, Service: 10.100.0.0/16)

Problem 2: Pod CIDR overlaps with Node Subnet
  Pod CIDR: 10.0.0.0/16
  Node Subnet: 10.0.1.0/24 (in VPC)
Solution: Use different ranges (e.g., Pod: 192.168.0.0/16, Node Subnet: 10.0.1.0/24)

Problem 3: Service CIDR overlaps with Node Subnet
  Service CIDR: 172.16.0.0/16
  Node Subnet: 172.16.1.0/24 (in VPC)
Solution: Use different ranges (e.g., Service: 10.100.0.0/16, Node Subnet: 172.16.1.0/24)
```

### ❌ Insufficient Subnet IPs

```
Problem: Small subnet with many LoadBalancers needed
Solution: Use larger subnet (/24 or bigger) or dedicated LoadBalancer subnet
```

### ❌ Invalid CIDR Range

```
Problem: Using invalid or disallowed IP range
  Pod CIDR: 8.8.8.0/24 (public IP range - not allowed)
Solution: Use private IP ranges: 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16
```

## Understanding Network Flow

```
┌─────────────────────────────────────────────────────────────┐
│                          VPC Network                         │
│                                                              │
│  ┌────────────────────────────────────────────────────────┐ │
│  │            Subnet (Specified in Subnet KRN)            │ │
│  │                                                        │ │
│  │  ┌──────────┐  ┌──────────┐  ┌────────────────────┐ │ │
│  │  │  Node 1  │  │  Node 2  │  │   LoadBalancer     │ │ │
│  │  │ (10.0.1) │  │ (10.0.2) │  │   (10.0.1.100)     │ │ │
│  │  └──────────┘  └──────────┘  └────────────────────┘ │ │
│  │       │              │                  │            │ │
│  └───────┼──────────────┼──────────────────┼────────────┘ │
│          │              │                  │               │
└──────────┼──────────────┼──────────────────┼───────────────┘
           │              │                  │
           │              │                  │
    ┌──────▼──────┐┌──────▼──────┐   ┌──────▼──────┐
    │  Pods using ││  Pods using │   │  External   │
    │  Pod CIDR   ││  Pod CIDR   │   │   Traffic   │
    │ 192.168.0.x ││ 192.168.1.x │   │             │
    └─────────────┘└─────────────┘   └─────────────┘
           │              │
           └──────┬───────┘
                  │
          ┌───────▼────────┐
          │ Services using │
          │  Service CIDR  │
          │  10.100.0.x    │
          └────────────────┘
```

## Next Steps

* Plan your node groups: [Managing Nodegroups](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/managing-nodegroups)
* Create your cluster: [Creating Cluster](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/creating-cluster)
* Configure add-ons: [Installing Addons](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/installing-addons)

## Need Help?

If you're unsure about network sizing:

* Start with default values for testing
* Monitor your cluster growth
* Contact support for production planning assistance


# Load Balancers

Load Balancers allow you to expose your Kubernetes services to external traffic. This guide covers creating and configuring LoadBalancer services in Krutrim Kubernetes Service using OpenStack Cloud Controller Manager (OCCM).

## What is a LoadBalancer Service?

A LoadBalancer service automatically provisions a cloud load balancer that routes external traffic to your application pods.

Benefits:

* External Access: Expose services to the internet
* Automatic Provisioning: Load balancer created automatically
* Health Checking: Built-in health monitoring
* High Availability: Traffic distributed across pods

{% hint style="info" %}
Important: For Layer 7 (L7) features like HTTP path-based routing, host-based routing, SSL/TLS termination, and HTTP header manipulation, always use Kubernetes Ingress controllers (like HAProxy, Kong, NGINX, or Traefik) behind a LoadBalancer service. Do not rely on the LoadBalancer for L7 functionality — use it as a simple Layer 4 entry point to your Ingress controller.
{% endhint %}

## How LoadBalancers Work in KKS

Krutrim Kubernetes Service uses OpenStack Cloud Controller Manager (OCCM) to manage LoadBalancer services:

```
┌─────────────────────────────────────────────────────────┐
│              Kubernetes LoadBalancer Service            │
└─────────────────┬───────────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────────┐
│         OpenStack Cloud Controller Manager (OCCM)       │
│         (Managed by Krutrim platform)                   │
└─────────────────┬───────────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────────┐
│          OpenStack Load Balancer (Octavia)              │
│          Created in your specified subnet               │
└─────────────────┬───────────────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────────────┐
│   External LoadBalancer: Floating IP (public internet)  │
│   Internal LoadBalancer: Subnet IP (private only)       │
└─────────────────────────────────────────────────────────┘
```

### IP Address Allocation

External LoadBalancers (Default):

* Receive a VIP (Virtual IP) from the cluster subnet
* Also get a Floating IP from the public IP pool (mapped to the VIP)
* Accessible from the internet via the floating IP
* Consume 1 IP from the cluster subnet

Internal LoadBalancers:

* Receive a VIP (Virtual IP) from the cluster subnet
* Only accessible within your VPC/private network
* Consume 1 IP from the cluster subnet

Example: Your cluster subnet: 10.0.1.0/24 (for nodes, pods, and LoadBalancers)

* 10 nodes use: 10 IPs
* 5 external LoadBalancers: 5 IPs (each also gets a floating IP)
* 3 internal LoadBalancers: 3 IPs
* Total used: 18 IPs from cluster subnet

Floating IPs (for external LoadBalancers only):

* Allocated from public IP pool
* Mapped to LoadBalancer VIPs
* 5 floating IPs for the 5 external LoadBalancers

Key Points:

* LoadBalancers use IPs from your cluster subnet
* Each LoadBalancer consumes 1 IP from the cluster subnet (for both internal and external)
* External LoadBalancers get an additional floating IP for internet access (from public IP pool)
* Plan your cluster subnet size to accommodate nodes, pods, and LoadBalancers

## Layer 4 (L4) vs Layer 7 (L7) Load Balancing

### Understanding the Recommended Architecture

Important: For any Layer 7 (L7) features, always use a Kubernetes Ingress controller - do not rely on the LoadBalancer for L7 functionality.

Layer 4 (L4) - Use LoadBalancer:

* Use LoadBalancer as a simple entry point - based on IP address and TCP/UDP port only
* Keep it simple: port forwarding to your Ingress controller or service
* Fast and efficient for TCP/UDP traffic
* Suitable for any TCP/UDP protocol (HTTP, HTTPS, database connections, etc.)

Layer 7 (L7) - Use Ingress Controllers:

* Do not rely on LoadBalancer for L7 features
* Use Ingress controllers for HTTP-based routing (URLs, headers, cookies)
* Advanced routing: path-based, host-based, header-based
* SSL/TLS termination at the Ingress controller level
* HTTP features: redirects, rewrites, authentication
* Full control over L7 behavior

### Why Use Ingress Controllers for L7

Even though the underlying infrastructure may have L7 capabilities, always use Ingress controllers for L7 functionality.

Recommended Ingress Controllers:

* NGINX Ingress Controller: Most popular, feature-rich
* HAProxy Ingress: High performance, enterprise features
* Kong Ingress: API gateway with plugins
* Traefik: Modern, cloud-native, automatic service discovery

Architecture Pattern:

```
Internet → LoadBalancer (L4 Entry Point) → Ingress Controller (L7 Logic) → Services → Pods
           └─ Simple port forwarding      └─ All L7 features here
```

Example Use Cases:

* Use LoadBalancer only (simple L4) when:
  * Exposing single service directly to the internet
  * Non-HTTP protocols (databases, custom TCP/UDP services)
  * Simple port-based forwarding
  * Maximum simplicity needed
* Use LoadBalancer + Ingress (L4 + L7) when:
  * Any HTTP/HTTPS application requiring L7 features
  * Multiple services behind single IP
  * Path-based routing: /api/\* → api-service, /web/\* → web-service
  * Host-based routing: api.example.com → api-service, [www.example.com](http://www.example.com) → web-service
  * SSL/TLS termination needed
  * HTTP redirects, rewrites, authentication
  * Cost optimization (one LoadBalancer for many services)
  * This is the recommended pattern for HTTP services

Quick Start with Ingress:

```yaml
# 1. Deploy ingress controller (e.g., NGINX) with LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer  # Single LoadBalancer for all ingress traffic
  selector:
    app: ingress-nginx
  ports:
    - port: 80
      targetPort: 80
    - port: 443
      targetPort: 443

---

# 2. Create Ingress resources for L7 routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
    - host: www.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80
```

Benefits of Using Ingress Controllers for L7:

* Proper L7 Handling: Full HTTP protocol support with proper routing logic
* Cost Savings: One LoadBalancer for many services instead of one per service
* L7 Features: Path routing, host routing, SSL termination, rewrites, redirects
* Flexibility: Easy to add/remove services without new LoadBalancers
* Control: Full control over L7 behavior instead of relying on platform defaults
* Standard: Kubernetes-native API with wide ecosystem support

{% hint style="warning" %}
Key Recommendation: Always use LoadBalancer as a simple L4 entry point and let your Ingress controller handle all L7 functionality. Do not depend on the LoadBalancer for HTTP routing, SSL termination, or other L7 features.
{% endhint %}

## Creating a LoadBalancer Service

### Basic LoadBalancer Service

Create a simple LoadBalancer service:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-web-app
  namespace: default
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
```

Apply the service:

```bash
kubectl apply -f loadbalancer-service.yaml
```

Check LoadBalancer status:

```bash
# Wait for external IP to be assigned
kubectl get service my-web-app -w

# Expected output for external LoadBalancer:
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
my-web-app   LoadBalancer   10.100.50.10   <pending>      80:32000/TCP   10s
my-web-app   LoadBalancer   10.100.50.10   203.0.113.45   80:32000/TCP   2m
                                           ↑
                                    Floating IP (public internet access)
```

Timeline: 2-5 minutes for LoadBalancer to be provisioned

For internal LoadBalancer:

```bash
# Internal LoadBalancer will show a private IP
NAME              TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
internal-service  LoadBalancer   10.100.50.20   10.200.5.10   80:32001/TCP   2m
                                                ↑
                                         VIP (private network only)
```

### Understanding Service Ports

```yaml
ports:
  - name: http
    protocol: TCP
    port: 80              # External port (LoadBalancer listens on)
    targetPort: 8080      # Pod port (application listens on)
    nodePort: 32000       # Node port (automatically assigned)
```

Port Mapping Flow:

```
External Request → LoadBalancer:80 → Node:32000 → Pod:8080
```

## LoadBalancer Annotations

OCCM supports extensive configuration through annotations. Below are commonly used annotations for Krutrim Cloud.

Note: Annotations that require OpenStack resource IDs (like floating-network-id, subnet-id, network-id, port-id, member-subnet-id) are managed by the Krutrim platform and should not be specified by users. The platform automatically configures the appropriate network resources.

### Basic Annotations

Internal vs External LoadBalancer

External LoadBalancer (default):

```yaml
metadata:
  name: public-service
  # No annotation needed, external is default
```

* Gets a VIP from the cluster subnet
* Also gets a Floating IP from public IP pool (mapped to the VIP)
* Accessible from the internet via floating IP
* Consumes 1 IP from cluster subnet

Internal LoadBalancer (private network only):

```yaml
metadata:
  name: internal-service
  annotations:
    service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
```

* Gets a VIP from the cluster subnet
* Only accessible within your VPC
* Consumes 1 IP from cluster subnet

### Connection and Timeout Settings

Connection Limits

Max connections per LoadBalancer:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/connection-limit: "100000"
```

Default: -1 (unlimited)

Timeout Configuration

Member connection timeout (backend connection timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-member-connect: "5000"
```

Member data timeout (backend read timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-member-data: "50000"
```

Client data timeout (idle connection timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-client-data: "50000"
```

TCP inspection timeout:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-tcp-inspect: "0"
```

Values: Milliseconds (e.g., 5000 = 5 seconds)

### Load Balancing Algorithm

Choose how traffic is distributed:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
```

{% stepper %}
{% step %}

### ROUND\_ROBIN (default)

* Distributes requests evenly
* Simple and effective
* Good for most use cases
  {% endstep %}

{% step %}

### LEAST\_CONNECTIONS

* Sends to pod with fewest connections
* Good for long-lived connections
* Better for uneven request loads
  {% endstep %}

{% step %}

### SOURCE\_IP

* Same client → same backend
* Session persistence
* Good for stateful applications
  {% endstep %}

{% step %}

### SOURCE\_IP\_PORT

* Same client IP and port → same backend
* Enhanced session persistence
  {% endstep %}
  {% endstepper %}

Example:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: session-app
  annotations:
    loadbalancer.openstack.org/lb-method: "SOURCE_IP"
spec:
  type: LoadBalancer
  selector:
    app: session-app
  ports:
    - port: 80
      targetPort: 8080
```

### Health Check Configuration

Health monitors check backend pod health and automatically remove unhealthy pods from the load balancer pool.

Enable Health Monitor:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
```

Default: If not specified, platform default behavior applies

Important: Health monitors are required for services with externalTrafficPolicy: Local

Health Check Parameters:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
    loadbalancer.openstack.org/health-monitor-max-retries-down: "3"
```

Parameters:

* enable-health-monitor: Enable/disable health monitoring (default: platform default)
* health-monitor-delay: Seconds between health checks (default: 10)
* health-monitor-timeout: Health check timeout in seconds (default: 5)
* health-monitor-max-retries: Consecutive successes to mark member healthy (default: 3)
* health-monitor-max-retries-down: Consecutive failures to mark member down (default: 3)

Important Constraint: health-monitor-timeout must be less than health-monitor-delay

Health Check Types

TCP Health Check (default for TCP services):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "5"
    loadbalancer.openstack.org/health-monitor-timeout: "3"
```

* Simply checks if TCP connection can be established
* Good for most TCP services

HTTP Health Check (automatic for HTTP listeners):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
```

* Performs HTTP GET request
* Checks for HTTP 200 response
* Automatically used when X-Forwarded-For is enabled

### X-Forwarded-For Header

Inserts client IP into HTTP headers for HTTP services.

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/x-forwarded-for: "true"
```

Effects:

* Forces creation of HTTP listener (instead of TCP)
* Adds X-Forwarded-For header with client IP
* Backend can read original client IP from header

### Restrict Access to Specific IP Ranges

Restrict which client IPs can access your LoadBalancer service using the loadBalancerSourceRanges field in the Service spec:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: internal-api
spec:
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "10.0.0.0/8"
    - "192.168.0.0/16"
  selector:
    app: api
  ports:
    - port: 8080
      targetPort: 8080
```

Format: List of CIDR blocks in the Service spec

Requirements:

* OpenStack Octavia API version >= v2.12
* Ignored if Octavia doesn't support this feature

This field supports updates - you can modify it after Service creation

### Additional Advanced Annotations

Set Custom Hostname:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/hostname: "myapp.example.com"
```

Use case: Enable PROXY protocol with custom DNS

Filter Target Nodes:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/node-selector: "env=production,region=east"
```

Format: Comma-separated key=value pairs

* All specified labels must match
* Can specify key without value to check only for key existence
* If not specified, all nodes are eligible targets

## Common LoadBalancer Configurations

### Example 1: Public Web Application (External with Health Checks)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: public-web
  namespace: production
  annotations:
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
    loadbalancer.openstack.org/timeout-client-data: "300000"  # 5 minutes
spec:
  type: LoadBalancer
  selector:
    app: web
    tier: frontend
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
    - name: https
      port: 443
      targetPort: 8443
      protocol: TCP
```

### Example 2: Internal Microservice (Private Network)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: internal-api
  namespace: backend
  annotations:
    service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
    loadbalancer.openstack.org/lb-method: "LEAST_CONNECTIONS"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
spec:
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "10.0.0.0/8"
  selector:
    app: api
    tier: backend
  ports:
    - name: api
      port: 8080
      targetPort: 8080
      protocol: TCP
```

### Example 3: Session-based Application (Source IP Affinity)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: session-app
  namespace: applications
  annotations:
    loadbalancer.openstack.org/lb-method: "SOURCE_IP"
    loadbalancer.openstack.org/timeout-client-data: "3600000"  # 1 hour
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  selector:
    app: session-app
  ports:
    - port: 80
      targetPort: 3000
```

### Example 4: High-Performance API (Connection Limits)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: high-perf-api
  namespace: production
  annotations:
    loadbalancer.openstack.org/lb-method: "LEAST_CONNECTIONS"
    loadbalancer.openstack.org/connection-limit: "500000"
    loadbalancer.openstack.org/timeout-member-connect: "3000"
    loadbalancer.openstack.org/timeout-member-data: "30000"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "5"
    loadbalancer.openstack.org/health-monitor-timeout: "3"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
spec:
  type: LoadBalancer
  selector:
    app: api
    performance: high
  ports:
    - port: 443
      targetPort: 8443
      protocol: TCP
```

### Example 5: HTTP Service with X-Forwarded-For

```yaml
apiVersion: v1
kind: Service
metadata:
  name: web-app-xff
  namespace: production
  annotations:
    loadbalancer.openstack.org/x-forwarded-for: "true"
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
```

Effect: Creates HTTP listener that adds X-Forwarded-For header with client IP

## Complete Annotation Reference

### User-Configurable Annotations

The following annotations can be used by users to configure LoadBalancer behavior:

| Annotation                                                    | Description                     | Example Value                                                             |
| ------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------- |
| `service.beta.kubernetes.io/openstack-internal-load-balancer` | Create internal LB              | `"true"`                                                                  |
| `loadbalancer.openstack.org/lb-method`                        | Load balancing algorithm        | `"ROUND_ROBIN"`, `"LEAST_CONNECTIONS"`, `"SOURCE_IP"`, `"SOURCE_IP_PORT"` |
| `loadbalancer.openstack.org/enable-health-monitor`            | Enable health monitoring        | `"true"`                                                                  |
| `loadbalancer.openstack.org/health-monitor-delay`             | Health check interval (seconds) | `"10"`                                                                    |
| `loadbalancer.openstack.org/health-monitor-timeout`           | Health check timeout (seconds)  | `"5"`                                                                     |
| `loadbalancer.openstack.org/health-monitor-max-retries`       | Successes to mark healthy       | `"3"`                                                                     |
| `loadbalancer.openstack.org/health-monitor-max-retries-down`  | Failures to mark down           | `"3"`                                                                     |
| `loadbalancer.openstack.org/timeout-client-data`              | Client idle timeout (ms)        | `"50000"`                                                                 |
| `loadbalancer.openstack.org/timeout-member-connect`           | Backend connect timeout (ms)    | `"5000"`                                                                  |
| `loadbalancer.openstack.org/timeout-member-data`              | Backend read timeout (ms)       | `"50000"`                                                                 |
| `loadbalancer.openstack.org/timeout-tcp-inspect`              | TCP inspection timeout (ms)     | `"0"`                                                                     |
| `loadbalancer.openstack.org/connection-limit`                 | Max connections                 | `"100000"`, `"-1"` (unlimited)                                            |
| `loadbalancer.openstack.org/x-forwarded-for`                  | Add X-Forwarded-For header      | `"true"`                                                                  |
| `loadbalancer.openstack.org/node-selector`                    | Node label selectors            | `"env=prod,region=east"`                                                  |
| `loadbalancer.openstack.org/hostname`                         | Custom hostname                 | `"myapp.example.com"`                                                     |

## Changing Service Types

### Converting from LoadBalancer to NodePort or ClusterIP

When you change a Service from type: LoadBalancer to type: NodePort or type: ClusterIP, the underlying OpenStack load balancer will be automatically deleted.

Important: If you want to convert the Service back to type: LoadBalancer, you must delete the following annotations from the Service:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/load-balancer-address: "10.230.159.141"
    loadbalancer.openstack.org/load-balancer-id: "c94b6e78-c7cc-4299-b68e-cbe9db80f51c"
```

Why is this necessary?

* These annotations are automatically added by OCCM when a LoadBalancer is created
* They point to the old (now deleted) LoadBalancer
* If present when converting back to LoadBalancer type, OCCM will try to reuse the non-existent LoadBalancer
* This will cause the Service to fail provisioning

Correct Procedure:

{% stepper %}
{% step %}

### 1. Change to NodePort/ClusterIP (LoadBalancer will be deleted)

Example:

```bash
kubectl patch service my-service -p '{"spec":{"type":"NodePort"}}'
```

{% endstep %}

{% step %}

### 2. Remove the annotations before converting back

Example:

```bash
kubectl annotate service my-service \
  loadbalancer.openstack.org/load-balancer-address- \
  loadbalancer.openstack.org/load-balancer-id-
```

{% endstep %}

{% step %}

### 3. Change back to LoadBalancer (new LoadBalancer will be created)

Example:

```bash
kubectl patch service my-service -p '{"spec":{"type":"LoadBalancer"}}'
```

{% endstep %}
{% endstepper %}

Alternative: Delete and recreate the Service:

```bash
# Export current service configuration
kubectl get service my-service -o yaml > service-backup.yaml

# Edit service-backup.yaml:
# - Change type to LoadBalancer
# - Remove load-balancer-address and load-balancer-id annotations

# Delete old service
kubectl delete service my-service

# Create new service
kubectl apply -f service-backup.yaml
```

Note: A new LoadBalancer will be created with a new IP address. Update your DNS records and client configurations accordingly.

## Troubleshooting LoadBalancers

### LoadBalancer Stuck in Pending

Symptoms:

* Service external IP shows
* LoadBalancer not created after 5+ minutes

Diagnosis Steps:

```bash
# Check the Service events for error messages
kubectl describe service <service-name>

# Look for Events section at the bottom of the output

# Events will show specific error messages about provisioning failures
```

{% stepper %}
{% step %}

### Invalid annotations

* Review Service YAML for typos in annotation names
* Verify annotation values are correct format
* Remove unsupported annotations
* Check service events for validation errors
  {% endstep %}

{% step %}

### Network or platform configuration issues

* Service events will show specific error details
* Contact Krutrim support with the event messages for assistance
  {% endstep %}
  {% endstepper %}

If LoadBalancer remains in pending state:

* Capture the output of kubectl describe service
* Note any error messages in the Events section
* Contact Krutrim support with the service description and events

### LoadBalancer Created but Not Accessible

Symptoms:

* External IP assigned
* Cannot access service from internet or internal network

Diagnosis Steps:

```bash
# 1. Check pod status
kubectl get pods -l app=<your-app>

# 2. Check service endpoints
kubectl get endpoints <service-name>

# 3. Test from within cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- sh
wget -O- http://<service-name>.<namespace>.svc.cluster.local

# 4. Check service configuration
kubectl get service <service-name> -o yaml
```

### Services with externalTrafficPolicy: Local

Special Requirements:

* Health monitors are required for externalTrafficPolicy: Local
* Without health monitor, traffic routing will fail

```yaml
apiVersion: v1
kind: Service
metadata:
  name: local-traffic-service
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"  # Required!
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local  # Requires health monitor
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080
```

## Best Practices

### ✅ Do's

1. Always Configure Health Checks:

   * Essential for production services
   * Required for externalTrafficPolicy: Local
   * Set realistic timeouts based on application behavior

   ```yaml
   loadbalancer.openstack.org/enable-health-monitor: "true"
   loadbalancer.openstack.org/health-monitor-delay: "10"
   loadbalancer.openstack.org/health-monitor-timeout: "5"
   ```
2. Set Appropriate Timeouts:

   * Configure client timeouts for long-running requests
   * Consider application response times
   * Plan for slow clients

   ```yaml
   loadbalancer.openstack.org/timeout-client-data: "300000"  # 5 minutes
   loadbalancer.openstack.org/timeout-member-data: "60000"   # 1 minute
   ```
3. Use Internal LoadBalancers for Internal Services:

   * Reduce costs (no floating IP)
   * Better security (not exposed to internet)
   * Faster response times (no public network hop)

   ```yaml
   service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
   ```
4. Restrict Access with Source Ranges:

   * Limit who can access your services
   * Use specific CIDRs instead of 0.0.0.0/0

   ```yaml
   spec:
     type: LoadBalancer
     loadBalancerSourceRanges:
       - "10.0.0.0/8"
       - "203.0.113.0/24"
   ```
5. Choose the Right Load Balancing Algorithm:
   * ROUND\_ROBIN: Default, good for stateless apps
   * LEAST\_CONNECTIONS: Better for uneven request loads
   * SOURCE\_IP: Required for session affinity
6. Monitor and Log:
   * Monitor LoadBalancer health and performance
   * Check OCCM logs for issues
   * Set up alerts for LoadBalancer failures
7. Use Descriptive Names:
   * Name services clearly
   * Add labels for organization
   * Document LoadBalancer purpose

### ❌ Don'ts

1. Don't Over-Provision LoadBalancers:
   * Each LoadBalancer has a cost and consumes resources
   * Use Kubernetes Ingress controllers (NGINX, HAProxy, Kong, Traefik) for L7/HTTP routing
   * Treat LoadBalancers as L4 (transport layer) - use Ingress for L7 (application layer) features
   * One Ingress controller with one LoadBalancer can route to many services
   * Avoid creating separate LoadBalancers for each HTTP service
2. Don't Rely on LoadBalancers for L7 Features:
   * Always use Ingress controllers for L7 functionality
   * LoadBalancer should be a simple L4 entry point only
   * For path-based routing, host-based routing, SSL termination → use Ingress controllers
   * Don't depend on LoadBalancer for HTTP routing, header manipulation, or SSL termination
3. Don't Ignore Health Check Configuration:
   * Default values may not suit your application
   * Test health check behavior before production
   * Monitor health check failures
   * Required for externalTrafficPolicy: Local
4. Don't Use Unrealistic Timeouts:
   * Too short → healthy pods marked as down
   * Too long → slow failure detection
   * Consider network latency
   * Allow for application warmup time
5. Don't Expose Everything Externally:
   * Use internal LoadBalancers for internal-only services
   * External exposure increases attack surface
   * Follow principle of least privilege
6. Don't Modify Platform-Managed Annotations:
   * Don't manually edit load-balancer-id
   * Don't set OpenStack resource IDs (network-id, subnet-id, etc.)
   * Platform manages these automatically
   * Modifying can break LoadBalancer functionality
7. Don't Forget About Costs:
   * Floating IPs may have costs
   * LoadBalancers have ongoing costs
   * Clean up unused LoadBalancers
   * Use Ingress controllers to consolidate services behind one LoadBalancer
8. Don't Skip Testing:
   * Test LoadBalancer access before production
   * Verify health checks work correctly
   * Test failover behavior
   * Validate timeout settings under load

## Additional Resources

* Official OpenStack CCM Documentation:
  * <https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/openstack-cloud-controller-manager/expose-applications-using-loadbalancer-type-service.md#service-annotations>
* Kubernetes Documentation:
  * <https://kubernetes.io/docs/concepts/services-networking/service/>
  * <https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer>
  * <https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip>

## Related Topics

* Using Ingress Controllers for L7 Load Balancing:
  * Recommended for all HTTP/HTTPS services: Use Kubernetes Ingress with controllers like NGINX, HAProxy, Kong, or Traefik
  * Do not rely on LoadBalancer for L7 features - use it only as a simple L4 entry point
  * LoadBalancer (L4) forwards traffic → Ingress Controller (L7) handles routing logic
  * Ingress provides full Layer 7 (L7) control: path-based routing, host-based routing, SSL/TLS termination, rewrites, redirects
  * Cost-effective: One LoadBalancer + Ingress controller can serve multiple services
* Service Mesh: For advanced traffic management, consider service mesh solutions like Istio or Linkerd, which can work alongside LoadBalancer services.
* Network Policies: Combine LoadBalancer services with Kubernetes Network Policies for comprehensive network security.


# Storage Configuration

This guide covers persistent storage configuration in Krutrim Kubernetes Service using Container Storage Interface (CSI) drivers.

## Understanding Storage in Kubernetes

Kubernetes provides several storage abstractions:

* **Volumes**: Temporary storage tied to pod lifecycle
* **PersistentVolumes (PV)**: Cluster-level storage resources
* **PersistentVolumeClaims (PVC)**: User requests for storage
* **StorageClass**: Dynamic provisioning configuration

## CSI Add-on Overview

The Container Storage Interface (CSI) driver enables dynamic storage provisioning in your cluster.

### What is CSI?

**CSI** is a standard interface for exposing block and file storage systems to containerized workloads on Kubernetes.

Benefits:

* ✅ Dynamic volume provisioning
* ✅ Automatic volume creation
* ✅ Volume snapshots
* ✅ Volume expansion
* ✅ Integration with cloud storage

## Critical: CSI Add-on Requirement

{% hint style="danger" %}
Default storage class is ONLY available if CSI Node Plugin add-on is enabled.

Without CSI:

* ❌ No default storage class
* ❌ Cannot create PersistentVolumeClaims
* ❌ No dynamic volume provisioning

With CSI:

* ✅ Default storage class available
* ✅ Can create PersistentVolumeClaims
* ✅ Dynamic volume provisioning works
  {% endhint %}

## Installing CSI Add-on

Install the CSI add-on to enable persistent storage in your cluster.

## Configuring Persistent Storage

### Prerequisites

Before configuring storage, ensure:

* ✅ **CSI Node Plugin Installed**:
  * CSI Node Plugin add-on: ACTIVE

### Verify Installation

```bash
# Check CSI pods are running
kubectl get pods -n kube-system | grep csi

# Expected output:
csi-cinder-nodeplugin-xxxxx     3/3   Running   0   3m
csi-cinder-nodeplugin-yyyyy     3/3   Running   0   3m

# Verify storage class is available
kubectl get storageclass

# Expected output:
NAME                    PROVISIONER                 RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION
csi-cinder-sc-qos-delete (default)   cinder.csi.openstack.org    Delete          Immediate   true
```

## Understanding Storage Classes

## Available Storage Classes

Once the CSI add-on is installed, a default storage class is automatically configured for your cluster.

### Default Storage Class

After CSI installation, the default storage class is automatically created:

```yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
  name: csi-cinder-sc-qos-delete
parameters:
  availability: nova
provisioner: cinder.csi.openstack.org
reclaimPolicy: Delete
volumeBindingMode: Immediate
```

### Storage Class Parameters

**Provisioner**: `cinder.csi.openstack.org`

* Uses OpenStack Cinder for block storage
* Provides persistent volumes backed by cloud storage

**Reclaim Policy**: `Delete`

* Volumes are deleted when PVC is deleted
* Data is permanently removed
* Use caution with production data

**Volume Binding Mode**: `Immediate`

* Volume is created immediately when PVC is created
* Does not wait for pod to be scheduled
* Volume may be created in different zone than pod

**Allow Volume Expansion**: `true`

* Volumes can be resized after creation
* Requires PVC and pod restart

## Using Persistent Storage

### Creating a PersistentVolumeClaim

#### Basic PVC

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-data
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  # storageClassName: krutrim-csi  # Optional, uses default if omitted
```

Apply PVC:

```bash
kubectl apply -f pvc.yaml
```

Check PVC Status:

```bash
kubectl get pvc my-app-data

# Expected states:

# Pending → Binding in progress

# Bound → Volume created and bound
```

### Access Modes

**ReadWriteOnce (RWO)**:

* Volume can be mounted read-write by a **single node**
* Most common mode
* Supported by default storage class

**ReadOnlyMany (ROX)**:

* Volume can be mounted read-only by **multiple nodes**
* Less common
* Check if supported

**ReadWriteMany (RWX)**:

* Volume can be mounted read-write by **multiple nodes**
* Requires special storage types (not block storage)
* Not supported by default Cinder CSI

### Using PVC in Pods

#### Pod with Volume Mount

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-storage
spec:
  containers:
  - name: app
    image: nginx:latest
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: my-app-data
```

#### StatefulSet with Volume Claim Template

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: database
spec:
  serviceName: database
  replicas: 3
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
      - name: postgres
        image: postgres:14
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi
```

Benefits of VolumeClaimTemplates:

* Each pod gets its own PVC
* PVC name includes pod name (data-database-0, data-database-1, etc.)
* Automatic creation and management

## Common Storage Scenarios

### Scenario 1: Web Application with User Uploads

```yaml
# PVC for uploads
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: uploads-storage
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
---
# Deployment using the PVC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
spec:
  replicas: 1  # Note: RWO limits to single replica
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: app
        image: my-web-app:latest
        volumeMounts:
        - name: uploads
          mountPath: /app/uploads
      volumes:
      - name: uploads
        persistentVolumeClaim:
          claimName: uploads-storage
```

### Scenario 2: Database with Persistent Storage

```yaml
# PVC for database
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
  namespace: database
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Gi
---
# StatefulSet for database
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: database
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:14
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
        ports:
        - containerPort: 5432
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: postgres-data
```

### Scenario 3: Shared Configuration Files

```yaml
# ConfigMap for config files (not PVC)
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  app.conf: |
    server {
      listen 80;
      server_name localhost;
    }
---
# Pod using ConfigMap
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: nginx:latest
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d
  volumes:
  - name: config
    configMap:
      name: app-config
```

Note: Use ConfigMap for configuration, PVC for data

### Scenario 4: Multiple Containers Sharing Data

```yaml
# Single PVC shared by containers in same pod
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-app
spec:
  containers:
  - name: writer
    image: writer-app:latest
    volumeMounts:
    - name: shared
      mountPath: /data
  - name: reader
    image: reader-app:latest
    volumeMounts:
    - name: shared
      mountPath: /data
      readOnly: true
  volumes:
  - name: shared
    persistentVolumeClaim:
      claimName: shared-data
```

## Managing Storage

### Viewing Storage Resources

```bash
# List storage classes
kubectl get storageclass

# List PersistentVolumes
kubectl get pv

# List PersistentVolumeClaims
kubectl get pvc -A

# Describe PVC for details
kubectl describe pvc my-app-data

# Check PVC events
kubectl get events --field-selector involvedObject.name=my-app-data
```

### Expanding Volumes

The default storage class supports volume expansion.

Step: Edit PVC

```bash
kubectl edit pvc my-app-data
```

Step: Increase Size (example)

```yaml
spec:
  resources:
    requests:
      storage: 20Gi  # Increased from 10Gi
```

Step: Restart Pod

```bash
# Delete pod to trigger remount (for Deployment)
kubectl delete pod <pod-name>

# For StatefulSet
kubectl rollout restart statefulset <statefulset-name>
```

Verification:

```bash
# Check PVC size
kubectl get pvc my-app-data

# Check from inside pod
kubectl exec <pod-name> -- df -h /data
```

Important notes:

* Can only increase size, not decrease
* Pod must be restarted for filesystem resize
* Some storage backends may take time to expand

### Deleting Storage

Delete PVC:

```bash
kubectl delete pvc my-app-data
```

What happens:

* PVC is deleted
* PV is deleted (due to `Delete` reclaim policy)
* Underlying storage is removed
* Data is permanently lost

Warning: Deleting PVC deletes data permanently!

Protecting Important Data:

* Option 1: Change Reclaim Policy

```bash
# Change PV reclaim policy to Retain
kubectl patch pv <pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
```

* Option 2: Backup Before Deletion

```bash
# Create snapshot or backup data before deleting
```

* Option 3: Don't Delete PVC
  * Keep PVC even if not in use
  * PVC doesn't cost money, storage does
  * Reattach to new pods when needed

## Storage Best Practices

{% stepper %}
{% step %}

### Size Appropriately

* Start with reasonable size
* Plan for growth (can expand later)
* Monitor usage regularly
  {% endstep %}

{% step %}

### Use Appropriate Access Modes

* ReadWriteOnce for most applications
* ReadOnlyMany for shared read-only data
* Understand access mode limitations
  {% endstep %}

{% step %}

### Plan for Data Persistence

* Important data: Use PVCs
* Temporary data: Use emptyDir
* Configuration: Use ConfigMaps/Secrets
  {% endstep %}

{% step %}

### Monitor Storage Usage

```bash
# Check PVC usage
kubectl exec <pod-name> -- df -h

# Monitor regularly
# Set up alerts for high usage
```

{% endstep %}

{% step %}

### Backup Critical Data

* Regular backups of databases
* Export important data
* Test restore procedures
  {% endstep %}

{% step %}

### Use StatefulSets for Stateful Apps

* Databases, queues, caches
* Automatic PVC management
* Stable network identities
  {% endstep %}
  {% endstepper %}

## Anti-Patterns / Don'ts

{% stepper %}
{% step %}

### Don't Use ReadWriteOnce for Multi-Replica Apps

```yaml
# ❌ Bad: Multiple replicas with RWO
replicas: 3
volumes:
- persistentVolumeClaim:
    claimName: shared-data  # RWO - only one can mount

# ✅ Good: Use StatefulSet with volumeClaimTemplates
# Or use single replica with RWO
```

{% endstep %}

{% step %}

### Don't Delete PVC Without Backup

* Always backup important data first
* Verify backups are restorable
* Document data recovery procedures
  {% endstep %}

{% step %}

### Don't Overprovision Storage

* Start reasonable, expand as needed
* Storage costs money
* Monitor actual usage
  {% endstep %}

{% step %}

### Don't Ignore Disk Full Errors

* Monitor disk usage
* Set up alerts at 80% usage
* Expand or clean up before full
  {% endstep %}

{% step %}

### Don't Store Secrets in Volumes

* Use Kubernetes Secrets
* Use proper secret management
* Don't write passwords to persistent storage
  {% endstep %}
  {% endstepper %}

## Troubleshooting Storage

### PVC Stuck in Pending

Symptoms:

* PVC status remains `Pending`
* No PV created

Possible Causes:

1. CSI add-on not installed
2. Storage provisioning in progress
3. Storage quota exceeded

Solution:

```bash
# Check CSI pods
kubectl get pods -n kube-system | grep csi

# Check PVC events
kubectl describe pvc <pvc-name>

# Check if storage provisioning completed
kubectl get pvc <pvc-name>

# Verify storage class exists
kubectl get storageclass
```

### Pod Cannot Mount Volume

Symptoms:

* Pod in `ContainerCreating` state
* Events show volume mount errors

Possible Causes:

1. PVC not bound
2. Node doesn't have CSI driver
3. Volume in use by another pod (RWO)

Solution:

```bash
# Check PVC status
kubectl get pvc

# Check pod events
kubectl describe pod <pod-name>

# Check CSI node plugin on node
kubectl get pods -n kube-system -l app=csi-cinder-nodeplugin -o wide

# If RWO, ensure only one pod uses volume
kubectl get pods -o wide | grep <pvc-name>
```

### Volume Out of Space

Symptoms:

* Application errors writing to disk
* Pod logs show "no space left on device"

Solution:

```bash
# Check current usage
kubectl exec <pod-name> -- df -h /data

# Expand volume (see Expanding Volumes section)
kubectl edit pvc <pvc-name>

# Increase storage size

# Restart pod

# Or clean up data
kubectl exec <pod-name> -- rm -rf /data/old-files
```

### Storage Class Not Found

Symptoms:

* PVC pending with "no storage class found"
* `kubectl get storageclass` shows nothing

Solution:

```bash
# Install CSI Node Plugin add-on

# Verify installation
kubectl get storageclass

# Check CSI pods
kubectl get pods -n kube-system | grep csi
```

## Storage Sizing Guidelines

### Application Types

Small Applications / Development:

```yaml
storage: 10-20Gi
```

Medium Applications / Production:

```yaml
storage: 50-100Gi
```

Databases:

```yaml
# Small database
storage: 100Gi

# Medium database
storage: 200-500Gi

# Large database
storage: 1Ti+
```

File Storage / Media:

```yaml
# Image hosting
storage: 200Gi-1Ti

# Video storage
storage: 1Ti+
```

Monitoring / Logging:

```yaml
# Prometheus (30 days retention)
storage: 100-200Gi

# Elasticsearch / Logging
storage: 500Gi-2Ti
```

## Additional Resources

* [Installing Add-ons](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/installing-addons) - Install CSI add-ons
* [Best Practices](broken://pages/8f36a824bf0b8e37d537731c3a9044d23842a672) - Storage optimization tips
* [Troubleshooting Guide](broken://pages/ddb69b507463367afd9c067d63cb5341a80fa3e8) - Common storage issues


# Upgrading Kubernetes

This guide covers the process of upgrading your Kubernetes cluster to a newer version in Krutrim Kubernetes Service.

## Overview

Upgrading a Kubernetes cluster in KKS is a two-phase process:

* Control Plane Upgrade: Upgrades the Kubernetes control plane components
* Node Group Upgrade: Upgrades worker nodes in each node group individually

Important: These are separate operations. Upgrading the cluster version only upgrades the control plane. You must upgrade each node group separately to complete the cluster upgrade.

## How Kubernetes Version Upgrade Works

### Phase 1: Control Plane Upgrade

When you upgrade the Kubernetes version:

```
Control Plane Upgrade (Automatic)

✓ API Server upgraded to new version
✓ Controller Manager upgraded
✓ Scheduler upgraded
✓ etcd compatibility verified

Worker Nodes: Still running OLD version
```

After control plane upgrade:

* ✅ Control plane runs the new Kubernetes version
* ⚠️ Worker nodes still run the old version
* ✅ Cluster remains operational (Kubernetes supports version skew)
* ⚠️ You must upgrade node groups to complete the process

### Phase 2: Node Group Upgrade

After upgrading the control plane, you must upgrade each node group:

```
Node Group Upgrade (Rolling Update Process)

1. New node with updated version joins cluster
2. Wait for new node to become Ready
3. Old node is cordoned (no new pods scheduled)
4. Old node is drained (pods evicted)
5. Old node is removed from cluster
6. Repeat for next node...
```

Rolling update ensures:

* No downtime for properly configured workloads
* Pods are rescheduled to healthy nodes
* One node upgraded at a time
* Cluster capacity maintained during upgrade

## Prerequisites

Before upgrading your Kubernetes cluster:

### Check Version Compatibility

* ✅ You can only upgrade to the next minor version (e.g., 1.27 → 1.28)
* ❌ Cannot skip versions (e.g., 1.27 → 1.29)
* ✅ Control plane must be upgraded before node groups
* ✅ Check available versions in Krutrim platform

### Review Release Notes

* Review Kubernetes release notes for the target version
* Check for deprecated APIs or breaking changes
* Verify your applications are compatible with the new version

### Backup Critical Data

* Backup any critical application data
* Document current cluster configuration
* Take note of current cluster state

### Check Cluster Health

```bash
# Check all nodes are Ready
kubectl get nodes

# Check all system pods are running
kubectl get pods -n kube-system

# Check critical workloads are healthy
kubectl get pods -A
```

## Upgrading the Control Plane

{% stepper %}
{% step %}

### Initiate Control Plane Upgrade

Upgrade the cluster's Kubernetes version through the Krutrim platform:

```bash
# Using Krutrim CLI (example)
krutrim cluster upgrade --cluster-id <cluster-id> --version 1.28.0

# Or via API
# Check Krutrim API documentation for specific endpoints
```

{% endstep %}

{% step %}

### Monitor Control Plane Upgrade

```bash
# Check cluster status
# Cluster status will show UPGRADING during the process
# Wait for cluster to return to PROVISIONED state
# This typically takes 5-15 minutes
```

{% endstep %}

{% step %}

### Verify Control Plane Upgrade

```bash
# Check API server version
kubectl version --short

# Output example:
# Client Version: v1.27.0
# Server Version: v1.28.0  ← Control plane upgraded

# Check node versions (still old version)
kubectl get nodes
# Nodes will still show v1.27.0
```

After control plane upgrade:

* ✅ Control plane is now running the new version
* ⚠️ Node groups still need to be upgraded
* ✅ Cluster is functional with version skew
  {% endstep %}
  {% endstepper %}

## Upgrading Node Groups

### Critical: Prepare for Node Group Upgrades

Before upgrading each node group, ensure smooth operation.

#### Ensure Pods Can Be Rescheduled

```bash
# Check PodDisruptionBudgets (PDBs)
kubectl get pdb -A

# Review each PDB to ensure it allows disruptions
kubectl describe pdb <pdb-name> -n <namespace>
```

Common issues:

* PDB with `minAvailable: 100%` will block draining
* Not enough replicas to satisfy PDB during drain
* Single-replica deployments without PDB

Solution example (adjust PDB):

```yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  minAvailable: 1  # Allow draining as long as 1 pod remains
  selector:
    matchLabels:
      app: myapp
```

#### Move Critical Workloads (If Necessary)

For critical single-replica workloads or workloads that cannot tolerate disruption:

```bash
# Option 1: Scale up temporarily
kubectl scale deployment <deployment-name> --replicas=2 -n <namespace>

# Option 2: Migrate to a different node group
# Use node selectors or taints to move workloads
kubectl edit deployment <deployment-name> -n <namespace>
```

#### Check Node Drain Blockers

```bash
# Check for bare pods (pods without controller)
kubectl get pods -A --field-selector spec.nodeName=<node-name>

# Bare pods will be deleted and not rescheduled
# Convert to Deployment/StatefulSet/DaemonSet before upgrade
```

{% stepper %}
{% step %}

### Upgrade Node Groups One by One

Important: Upgrade node groups one at a time to maintain cluster stability.

Recommended upgrade order:

* Non-critical node groups first (development, testing)
* General workload node groups (application nodes)
* Critical node groups last (production, stateful workloads)
  {% endstep %}

{% step %}

### Upgrade Process for Each Node Group

```bash
# Using Krutrim CLI (example)
krutrim nodegroup upgrade \
  --cluster-id <cluster-id> \
  --nodegroup-id <nodegroup-id> \
  --version 1.28.0

# Or via API
# Check Krutrim API documentation for specific endpoints
```

{% endstep %}

{% step %}

### Monitor Node Group Upgrade

During the upgrade, the platform performs a rolling update:

```bash
# Watch nodes being updated
kubectl get nodes -w
```

Example output:

```
NAME         STATUS   ROLES    AGE   VERSION
node-1-old   Ready    <none>   10d   v1.27.0
node-2-old   Ready    <none>   10d   v1.27.0
node-3-new   Ready    <none>   1m    v1.28.0  ← New node joins
node-1-old   Ready,SchedulingDisabled  10d  v1.27.0  ← Old node cordoned
node-1-old   NotReady,SchedulingDisabled  10d  v1.27.0  ← Draining
# node-1-old removed
node-4-new   Ready    <none>   1m    v1.28.0  ← Next new node joins
```

Per-node process:

1. New node with updated version is created
2. New node joins cluster and becomes Ready
3. Old node is cordoned (no new pods scheduled)
4. Old node is drained (pods evicted gracefully)
5. Old node is removed after successful drain
6. Process repeats for next node
   {% endstep %}

{% step %}

### Handle Stuck Node Upgrades

Symptoms:

* Node group upgrade stuck in UPGRADING state
* Old node stuck in "Draining" state
* Node group upgrade not progressing

Cause: Old node cannot be drained due to:

* PodDisruptionBudget blocking drain
* Pods with `emptyDir` volumes
* Bare pods (no controller)
* Pods with local storage

Diagnosis:

```bash
# Check which pods are blocking drain
kubectl get pods -A --field-selector spec.nodeName=<stuck-node-name>

# Check PodDisruptionBudgets
kubectl get pdb -A

# Check for drain events
kubectl get events --field-selector involvedObject.name=<stuck-node-name>
```

Resolution options:

Option 1: Fix PodDisruptionBudget

```bash
# Temporarily adjust PDB to allow draining
kubectl edit pdb <pdb-name> -n <namespace>
# Change minAvailable or maxUnavailable to allow disruption
```

Option 2: Scale Up Application

```bash
# Add more replicas to satisfy PDB during drain
kubectl scale deployment <deployment-name> --replicas=3 -n <namespace>
```

Option 3: Delete Blocking Pods (Careful!)

```bash
# For bare pods or stuck pods (understand impact first!)
kubectl delete pod <pod-name> -n <namespace> --grace-period=0 --force
```

Option 4: Contact Support

```bash
# If issue persists, contact Krutrim support with:
# - Cluster ID
# - Node group ID
# - Stuck node name
# - Output of: kubectl get pods -A --field-selector spec.nodeName=<node-name>
```

{% endstep %}

{% step %}

### Verify Node Group Upgrade

After each node group upgrade completes:

```bash
# Check all nodes in the node group are updated
kubectl get nodes -l nodegroup=<nodegroup-name>

# Verify node versions
kubectl get nodes -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion

# Check all pods are running
kubectl get pods -A -o wide

# Verify workloads are healthy
kubectl get deployments -A
kubectl get statefulsets -A
```

{% endstep %}

{% step %}

### Repeat for Remaining Node Groups

Repeat the previous steps for each remaining node group until all node groups are upgraded.
{% endstep %}
{% endstepper %}

## Best Practices for Smooth Upgrades

Do's

* Always Upgrade Control Plane First
  * Control plane must be at the same or newer version than nodes
  * Node groups cannot be newer than control plane
* Upgrade Node Groups One at a Time
  * Wait for each node group upgrade to complete
  * Verify workloads are healthy before proceeding
  * Maintain cluster stability
* Prepare Your Workloads
  * Ensure multiple replicas for critical services
  * Configure appropriate PodDisruptionBudgets
  * Use Deployments/StatefulSets instead of bare pods

Example PDB:

```yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: myapp-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: myapp
```

* Test Node Drainability Before Upgrade

```bash
# Test if a node can be drained (dry run)
kubectl drain <node-name> --dry-run=client --ignore-daemonsets
```

* Monitor During Upgrade

```bash
# Watch nodes
kubectl get nodes -w

# Watch pods being rescheduled
kubectl get pods -A -w

# Check events
kubectl get events -A --watch
```

* Schedule Upgrades During Maintenance Windows
  * Plan upgrades during low-traffic periods
  * Notify users of potential brief disruptions
  * Have rollback plan ready
* Upgrade Non-Production Clusters First
  * Test upgrade process in dev/staging
  * Identify potential issues before production
  * Validate application compatibility

Don'ts

* Don't Skip Kubernetes Versions
  * ❌ Cannot upgrade 1.27 → 1.29
  * ✅ Must upgrade 1.27 → 1.28 → 1.29
* Don't Upgrade Multiple Node Groups Simultaneously
  * Can cause cluster instability
  * Harder to troubleshoot issues
  * May exceed resource limits
* Don't Ignore PodDisruptionBudgets
  * PDBs can block node draining
  * Review and adjust PDBs before upgrade
  * Ensure PDBs allow at least some disruption
* Don't Use Bare Pods in Production
  * Bare pods are deleted during drain (not rescheduled)
  * Always use Deployments, StatefulSets, or DaemonSets
  * Controllers ensure pods are recreated
* Don't Upgrade Without Testing
  * Test upgrade in non-production first
  * Verify application compatibility
  * Check for deprecated APIs
* Don't Forget About Version Skew
  * Control plane and nodes can differ by 1 minor version
  * Don't leave nodes on old version indefinitely
  * Complete all node group upgrades within reasonable time
* Don't Ignore Failed Drains
  * Investigate why drain failed
  * Fix underlying issue
  * Don't force drain without understanding impact

## Troubleshooting Upgrade Issues

<details>

<summary>Control Plane Upgrade Stuck</summary>

Symptoms:

* Cluster stuck in UPGRADING state
* Control plane upgrade not completing

Solution:

* Check cluster status in Krutrim platform
* Review error messages
* Contact Krutrim support with cluster ID

</details>

<details>

<summary>Node Group Upgrade Not Starting</summary>

Symptoms:

* Node group remains in current version
* No new nodes being created

Possible Causes:

* Control plane not upgraded yet
* Invalid target version
* Insufficient quotas

Solution:

```bash
# Verify control plane is upgraded
kubectl version --short

# Check node group status in Krutrim platform

# Verify target version is valid

# Check OpenStack quotas for instance creation
```

</details>

<details>

<summary>Pods Failing After Upgrade</summary>

Symptoms:

* Pods in CrashLoopBackOff after upgrade
* Services not working correctly

Possible Causes:

* Application incompatible with new Kubernetes version
* Deprecated APIs removed
* Configuration issues

Solution:

```bash
# Check pod logs
kubectl logs <pod-name> -n <namespace>

# Check pod events
kubectl describe pod <pod-name> -n <namespace>

# Review Kubernetes deprecation notices

# Check release notes for breaking changes

# Roll back if necessary (may require cluster restore)
```

</details>

<details>

<summary>Node Stuck in NotReady After Upgrade</summary>

Symptoms:

* New node stuck in NotReady state
* Node not joining cluster properly

Solution:

```bash
# Check node conditions
kubectl describe node <node-name>

# Check kubelet logs on the node
# (requires node access)

# Check CNI pods
kubectl get pods -n kube-system -l k8s-app=cilium

# Contact Krutrim support if issue persists
```

</details>

## Version Skew Policy

Kubernetes supports running control plane and nodes at different versions (within limits):

Supported Version Skew:

```
Control Plane: v1.28.x
Node Groups:   v1.27.x or v1.28.x  ✅ Supported (1 minor version difference)
Node Groups:   v1.26.x             ❌ Not supported (2 minor versions)
```

Recommendations:

* Upgrade control plane first
* Upgrade all node groups within 1-2 weeks
* Don't leave node groups more than 1 version behind
* Complete upgrades before next version release

## Rollback Considerations

Important: Kubernetes upgrades are typically one-way operations.

Control Plane Rollback:

* Not typically supported
* May require cluster restore from backup
* Contact Krutrim support for assistance

Node Group Rollback:

* Can create new node group with old version
* Migrate workloads to old version node group
* Remove upgraded node group

Prevention is Better:

* Test upgrades in non-production first
* Verify application compatibility
* Have rollback plan documented
* Take backups before upgrading

## Post-Upgrade Tasks

After completing the upgrade:

### Verify Cluster Health

```bash
# Check all nodes are running new version
kubectl get nodes -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion

# Check all pods are running
kubectl get pods -A

# Check system components
kubectl get pods -n kube-system

# Check critical workloads
kubectl get deployments -A
kubectl get statefulsets -A
```

### Update Documentation

* Document the upgrade date and version
* Note any issues encountered and resolutions
* Update cluster documentation with new version

### Update Client Tools

```bash
# Update kubectl to match cluster version
# Download from: https://kubernetes.io/docs/tasks/tools/

# Verify kubectl version
kubectl version --client
```

### Review Deprecated APIs

* Check for deprecated API warnings
* Update manifests to use newer APIs
* Test applications thoroughly

### Monitor Cluster

* Monitor cluster performance
* Watch for any unusual behavior
* Check application metrics and logs

## Additional Resources

* Kubernetes Release Notes: <https://kubernetes.io/releases/>
* Krutrim Documentation: Check platform docs for version upgrade procedures
* Version Skew Policy: <https://kubernetes.io/releases/version-skew-policy/>

## Related Guides

* [Managing Node Groups](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/managing-nodegroups) - Node group operations
* [Creating a Cluster](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/creating-cluster) - Initial cluster setup
* [Installing Add-ons](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/installing-addons) - Managing cluster add-ons


# Billing for K8s and Load Balancer

### Load Balancer Billing

| Service                   | Flavor               | Unit | Price / Hour | Price / Month |
| ------------------------- | -------------------- | ---- | ------------ | ------------- |
| Application Load Balancer | Base Charge          | Hour | ₹8.00        | ₹5,840        |
| Application Load Balancer | Data Transfer Charge | GB   | --           | ₹0.40         |
| Network Load Balancer     | Base Charge          | Hour | ₹8.00        | ₹5,840        |
| Network Load Balancer     | Data Transfer Charge | GB   | --           | ₹0.20         |

Kubernetes Billing

| Service    | Flavor        | Unit | Price / Hour | Price / Month |
| ---------- | ------------- | ---- | ------------ | ------------- |
| Kubernetes | Control Plane | Hour | ₹7.00        | ₹5,110        |


# Databases

## Introduction

Krutrim Cloud Database as a Service (DBaaS) is a fully managed database offering designed to help you build, run, and scale applications without worrying about the operational complexity of database management. With Krutrim Cloud DBaaS, you can provision production-ready databases in minutes while we take care of reliability, availability, scalability, and ongoing maintenance.

Currently, we provide the following managed database engines:

* **Relational Databases (RDBMS):** MySQL and PostgreSQL
* **NoSQL Databases:** MongoDB

These databases are delivered as managed services, meaning we handle critical operational tasks such as database provisioning, patching, backups, replication, monitoring, and failover. This allows you to focus on application development and business logic instead of database administration. This is suitable for a wide range of use cases - from development and testing environments to mission-critical production systems - offering a secure, scalable, and reliable foundation for modern cloud-native applications.

## Choosing the Right Database

**Relational Databases (RDBMS)**\
Relational databases are best suited for applications that require strong consistency, well-defined schemas, and complex queries across related data. You should choose an RDBMS when your workload involves transactional operations, data integrity constraints, joins, or financial-grade accuracy—such as payments, order management, ERP, CRM, or core business systems. Krutrim Cloud DBaaS currently offers **MySQL** and **PostgreSQL** as fully managed relational database services, providing ACID-compliant transactions, reliable performance, and built-in high availability.

**NoSQL Databases**\
NoSQL databases are ideal for workloads that need flexible schemas, horizontal scalability, and high throughput at low latency. They work well for applications dealing with semi-structured or unstructured data, such as user profiles, content catalogs, session stores, event data, and real-time analytics. When your data model evolves frequently or your application needs to scale rapidly, NoSQL is often the better choice. Krutrim Cloud DBaaS currently provides **MongoDB** as a fully managed NoSQL document database, enabling scalable, schema-flexible application development with minimal operational overhead.

## Configurations

Krutrim DBaaS offers predefined instance configurations to simplify capacity planning while covering a wide range of workloads. Each configuration bundles vCPU, RAM, and minimum storage requirements.

<table><thead><tr><th width="151.78125">Tier Name</th><th width="183.609375">Configuration</th><th>Storage Minimum</th><th>Intended Use Case</th></tr></thead><tbody><tr><td>Starter</td><td>2 vCPU, 4 GB RAM</td><td>40 GB</td><td>Small dev/test, low traffic, prototypes.</td></tr><tr><td>Growth</td><td>4 vCPU, 8 GB RAM</td><td>100 GB</td><td>Early production, moderate traffic, few users.</td></tr><tr><td>Business</td><td>8 vCPU, 16 GB RAM</td><td>200 GB</td><td>Production service, steady traffic, analytics.</td></tr><tr><td>Enterprise</td><td>16 vCPU, 32 GB RAM</td><td>400 GB</td><td>High load, mission-critical, many concurrent queries.</td></tr></tbody></table>

## Storage

* Storage is provisioned separately and billed per GB per month.
* Minimum storage is enforced based on the selected tier.
* Users can expand storage at any time without downtime.

## High Availability and Replicas

You can choose a cluster configuration based on your **availability, fault-tolerance, and read-scalability** requirements. Adding replicas improves resilience and allows your database to continue serving traffic even if a node fails.

Krutrim Cloud DBaaS includes **automatic failover** for all replica-based configurations, ensuring high availability with minimal operational effort.

**Automatic failover includes:**

* Continuous health monitoring of the primary node
* Automatic promotion of a healthy replica if the primary node fails
* Minimal disruption to application connectivity
* No manual intervention required

\
We have the following replica configurations for the respective DB engine:

#### MySQL

1. **Two Standby Nodes** - This includes 1 primary and 2 replicas. Each replica has the same compute and storage specs as the primary. Billing becomes 3x, where x is the price of the primary node.
2. **No Standby Node** - This includes only the primary node.

#### PostgreSQL

1. **Two Standby Nodes** - This includes 1 primary and 2 replicas. Each replica has the same compute and storage specs as the primary. Billing becomes 3x, where x is the price of the primary node.
2. **One Standby Node** - This includes 1 primary and 1 replica. The replica has the same compute and storage specs as the primary. Billing becomes 2x, where x is the price of the primary node.
3. **No Standby Node** - This includes only the primary node.

#### MongoDB

1. **Two Standby Nodes** - This includes 1 primary and 2 replicas. Each replica has the same compute and storage specs as the primary. Billing becomes 3x, where x is the price of the primary node.
2. **No Standby Node** - This includes only the primary node.

## Backups

Backups help protect your database from accidental deletion, corruption, or system failures. Krutrim DBaaS provides a flexible, policy-based backup system that lets you automatically create and retain database backups on a schedule you control. Backups are stored securely in Object Storage and can be used later to restore your database to a previous state.

[Learn how to create a backup policy](/basics/core-infrastructure/databases/creating-backups)

#### How the Backup System Works

The backup system is built around backup policies. A backup policy defines:

* How often backups are taken (schedule)
* How many backups are retained
* When older backups are automatically deleted

Once configured, backups run automatically without any manual intervention.

### Maximum Backups (Retention)

The **Maximum Backups** setting controls how many backups are retained for your database.

* You can quickly choose common retention values like **3, 7, 14, or 30 backups**, or define a **custom** number.
* When the maximum limit is reached, **older backups are automatically deleted**.
* This helps manage storage costs while ensuring you always have recent restore points available.

**Example:**\
If you select **7 backups** and your schedule runs daily, Krutrim Cloud will always retain the most recent 7 days of backups.

### Backup Schedule

The **Backup Schedule** defines *when* backups are created. This uses a simple, cron-style scheduling system where you can specify one or more of the following fields:

* **Minute (0–59)** – The exact minute the backup runs
* **Hour (0–23)** – The hour of the day
* **Day (1–31)** – Specific day of the month
* **Month** – Specific month(s)
* **Weekday** – Specific day(s) of the week

You can leave fields set to **“Any”** if you don’t want to restrict them.

#### Common Scheduling Examples

* **Every 30 minutes**
  * Minute: `30`
  * Leave all other fields empty
* **Daily at 2:30 AM**
  * Minute: `30`
  * Hour: `2`
* **Weekly backup every Sunday at 3:00 AM**
  * Minute: `0`
  * Hour: `3`
  * Weekday: `Sunday`
* **Monthly backup on the 1st at midnight**
  * Minute: `0`
  * Hour: `0`
  * Day: `1`

## Billing

Billing is based on the compute and storage configuration, as well as the number of replicas.

**Storage** is billed at **Rs 7.88/GB/month**, i.e. Rs 0.01/GB/hour. Storage charges are over and above the configuration price.

Backups are associated with Object Storage buckets, and are billed within the Object Storage section only.&#x20;

{% hint style="warning" %}
Please ensure you have a minimum credit balance of Rs 500, in order to create a new database. Additionally if the credit balance goes below 0, the database is allowed to use upto Rs 1,500 worth of credits, after which the instance will be deleted. It's recommended to create backup policies to avoid data loss in such cases.
{% endhint %}

Here is the billing table for each DB engine, based on configuration selected:

#### MySQL

| Configuration      | Number of Replicas | Price         |
| ------------------ | ------------------ | ------------- |
| 2 vCPU, 4 GB RAM   | 1                  | Rs 3.15/hour  |
|                    | 3                  | Rs 9.45/hour  |
| 4 vCPU, 8 GB RAM   | 1                  | Rs 6.84/hour  |
|                    | 3                  | Rs 20.53/hour |
| 8 vCPU, 16 GB RAM  | 1                  | Rs 16.22/hour |
|                    | 3                  | Rs 48.67/hour |
| 16 vCPU, 32 GB RAM | 1                  | Rs 32.44/hour |
|                    | 3                  | Rs 97.33/hour |

#### PostgreSQL

| Configuration      | Number of Replicas | Price         |
| ------------------ | ------------------ | ------------- |
| 2 vCPU, 4 GB RAM   | 1                  | Rs 3.15/hour  |
|                    | 2                  | Rs 6.30/hour  |
|                    | 3                  | Rs 9.45/hour  |
| 4 vCPU, 8 GB RAM   | 1                  | Rs 6.84/hour  |
|                    | 2                  | Rs 13.69/hour |
|                    | 3                  | Rs 20.53/hour |
| 8 vCPU, 16 GB RAM  | 1                  | Rs 16.22/hour |
|                    | 2                  | Rs 32.44/hour |
|                    | 3                  | Rs 48.67/hour |
| 16 vCPU, 32 GB RAM | 1                  | Rs 32.44/hour |
|                    | 2                  | Rs 64.89/hour |
|                    | 3                  | Rs 97.33/hour |

#### MongoDB

| Configuration      | Number of Replicas | Price         |
| ------------------ | ------------------ | ------------- |
| 2 vCPU, 4 GB RAM   | 1                  | Rs 3.15/hour  |
|                    | 3                  | Rs 9.45/hour  |
| 4 vCPU, 8 GB RAM   | 1                  | Rs 6.84/hour  |
|                    | 3                  | Rs 20.53/hour |
| 8 vCPU, 16 GB RAM  | 1                  | Rs 16.22/hour |
|                    | 3                  | Rs 48.67/hour |
| 16 vCPU, 32 GB RAM | 1                  | Rs 32.44/hour |
|                    | 3                  | Rs 97.33/hour |


# Creating a Database

1. Click on the "Create Database" button on the 'Core Infrastructure > Databases' page.
2. Select your desired database type - relational or NoSQL database.
3. Select your DB engine and version.
4. Choose a suitable configuration from the available options, depending on your use case. Each configuration comes with specific compute specs and minimum storage (Storage charges are over and above the configuration price).
5. You can increase the storage to be configured, from the 'Select Storage' section. You can also increase storage after deployment.
6. You can add additional replicas to maintain high availability and automatic failover for your database. The replica configurations differ between DB engines, and incur additional charges.
7. Enter your DB and Network details such as DB name, VPC and Subnet.
8. Optionally, you can also [create a backup policy](/basics/core-infrastructure/databases/creating-backups) for your database. Backups are associated with Object Storage buckets, and are billed within the Object Storage section only.&#x20;

{% hint style="warning" %}
Please ensure you have a minimum credit balance of Rs 500, in order to create a new database. Additionally if the credit balance goes below 0, the database is allowed to use upto Rs 1,500 worth of credits, after which the instance will be deleted. It's recommended to create backup policies to avoid data loss in such cases.
{% endhint %}


# Creating Backups

1. Add a backup policy name.
2. Select your storage bucket, or create a new one. Provide your access key and secret key for that bucket.
3. You can select the maximum number of backups/retention copies (number of backups retained before the oldest backup is deleted).
4. Configure the **Backup Schedule** using the time and frequency fields. You can add multiple backup schedules after deployment, via the 'View Database' page. Common examples:
   1. **Every 30 minutes:** Minute: 30, leave others empty
   2. **Daily at 2:30 AM:** Minute: 30, Hour: 2, leave others empty
   3. **Weekly backup on Sunday at 3:00 AM:** Minute: 0, Hour: 3, Weekday: Sunday
   4. **Monthly on 1st at midnight:** Minute: 0, Hour: 0, Day: 1


# Managing a Database

1. You can manage your database from the **Actions** menu on the **Core Infrastructure > Databases** page.
2. Use the **View** option to access and copy connection details such as host, port, username, password, and connection URL.
3. The **Backups** tab lets you view existing backup schedules and backup history. You can also edit current schedules or create new ones as needed.
4. From the **Actions** menu, you can pause or restart the database, upgrade the database version, update allocated storage, and restore the database from an existing backup.


# AI Studio

## What is AI Studio?

AI Studio is an end-to-end platform that empowers developers, researchers, and enterprises to explore, fine-tune, evaluate, and deploy large AI models—without the hassle of managing infrastructure or engineering complexity.

Whether you're experimenting with foundational models, adapting them to your domain, or scaling them for production—AI Studio provides everything in one place.

***

### Why AI Studio?

Today’s AI demands go beyond access to pre-trained models. Organizations need infrastructure flexibility, customization workflows, and robust evaluation capabilities. AI Studio addresses this with:

* **Curated Model Catalog**: Access top-performing models in text, vision, speech, and multimodal domains.
* **No-Code Fine-Tuning**: Customize models with your data using efficient techniques like LoRA.
* **Integrated Evaluation**: Benchmark functional and performance metrics before deployment.
* **Scalable Deployment**: Launch models on-demand or via dedicated endpoints with GPU-backed infrastructure.

***

### Core Capabilities

#### Model Catalog

* Browse a curated selection of foundational and fine-tuned models.
* Each model card includes:
  * Overview and intended use cases
  * Licensing and attribution
  * GitHub repository links (if available)
  * API model string and sample usage
  * Interactive playground for real-time experimentation

#### Inferencing

* Run inference directly on models using APIs or the playground.
* Control parameters such as:
  * `temperature`, `top_p`, `max_tokens`, `logit_bias`, etc.
* Transparent, token-based pay-as-you-go pricing.

#### Fine-Tuning

* Fine-tune models such as Llama-3 and Mistral using LoRA adapters.
* Upload datasets in `instruction`, `input`, `output` JSON format.
* Monitor checkpoint progress and deploy fine-tuned versions directly.
* Supports customization for specific domains such as healthcare, legal, or customer support.

#### Evaluation

* **Model Evaluation**:
  * Evaluate task performance using datasets such as MMLU, BoolQ, HellaSwag, GSM8k, and TruthfulQA.
  * Multi-language support, including Indic languages.
  * Metrics include accuracy, relevance, and ethicality.
* **Performance Evaluation**:
  * Measure latency (TTFT, inter-token, end-to-end), throughput, and token counts.
  * Configure test load parameters such as concurrency, input/output token length, etc.
  * Compare evaluation runs across models and versions.

#### Deployment

* **On-Demand Deployment**:
  * Quick, pay-per-use deployment for experimentation or low-volume tasks.
* **Dedicated Deployment**:
  * Persistent endpoints using dedicated GPUs like NVIDIA H100.
  * Recommended for high-availability production use cases.
  * Deployment cost is based on GPU time usage.
* **Management Features**:
  * Monitor deployment status
  * Bring down unused deployments to avoid unnecessary costs

***

### Who is AI Studio For?

* **Developers & Engineers**: Build and integrate AI-powered features quickly using APIs and SDKs.
* **Researchers & Data Scientists**: Experiment with model architectures and datasets without infrastructure setup.
* **Product & Business Teams**: Evaluate and compare models to inform decisions about product integration.

***

### How It Works

1. **Explore** the Model Catalog and try out models in the playground or via API.
2. **Fine-Tune** a model using your own dataset if needed.
3. **Evaluate** both task and performance metrics using built-in tools.
4. **Deploy** the best model variant with on-demand or persistent infrastructure.
5. **Monitor** usage, costs, and metrics to ensure ongoing optimization.

***

### Key Advantages

* End-to-end AI model lifecycle support in a single platform
* Access to top open-source and proprietary models
* Efficient and scalable fine-tuning using LoRA
* Built-in evaluation with task and operational metrics
* Flexible deployment and billing options
* Developer-friendly experience with interactive playgrounds and starter code

***

### Next Steps

* Get Started with Quickstart
* Browse the Model Catalog
* Fine-Tune Your First Model
* Evaluate Your Model
* Deploy to Production

***


# Model Catalogue

## Model Catalog

The Model Catalogue is your launchpad for working with large AI models on AI Studio.\
In a single view, you can **discover models, inspect costs and licenses, run live tests in the Playground, and copy ready-to-use API snippets**—all before writing a line of production code.

***

### What You Can Do in the Catalogue

* **Search & filter** models by model name, modality (text-generation, multimodal, speech-to-text, and more) or provider.
* **Inspect key metadata** at a glance: model type, pricing tag, model provider
* **Compare alternatives quickly**—sort by date of addition and number of parameter.
* **Open a Playground** session directly from the card to test prompts or upload inputs.
* **Copy starter cURL/Python code** pre-filled with the correct `model` string.
* **Move to the next step** (fine-tune, evaluate, deploy) without leaving the Models section.

***

### Supported Modalities

| Modality           | Typical Use Cases                              |
| ------------------ | ---------------------------------------------- |
| Text-Generation    | Chatbots, summarisation, code completion       |
| Text-to-Embedding  | Semantic search, recommendation engines        |
| Image-Text-to-Text | Image captioning, visual Q\&A                  |
| Speech-to-Text     | Transcription, voice-assistant pipelines       |
| Text-to-Speech     | Voice synthesis, IVR systems                   |
| Multimodal         | Combined vision & language reasoning           |
| Tokenizer          | Stand-alone tokenisation for offline pipelines |

***

### Model Card Overview

A Model Card contains three tabs:

| Tab              | Purpose                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **Playground**   | Run interactive tests. Text models expose `temperature`, `top_p`, `max_tokens`, etc.; speech/image models accept uploads. |
| **Starter Code** | Copy cURL and Python snippets that call the production endpoint with minimal setup.                                       |
| **Overview**     | Architecture notes, training data summary, benchmarks, responsible-AI statements, and license details.                    |

Common header tags—**pricing**, **license**, **GitHub**, **Base Model / Fine-tuned**—let you evaluate suitability at a glance.

***

### Quickstart · Trying a Model

1. Locate a model card and open **Playground**.
2. Enter a prompt or upload an input sample.
3. Adjust parameters if needed and click **Run**.
4. Review the output.
5. Switch to **Starter Code**, copy the snippet, and replace `"<your secret key here>"` with your own token.

***

### Choosing the Right Model

| Consideration    | Practical Guidance                                                                    |
| ---------------- | ------------------------------------------------------------------------------------- |
| Task Fit         | Match the modality to your problem (e.g., speech-to-text for call recordings).        |
| Latency vs Cost  | Smaller models are cheaper and faster; larger models often deliver higher quality.    |
| Domain Alignment | Fine-tune when a base model’s answers are too generic for specialised content.        |
| Licensing        | Confirm the license permits commercial or derivative use if your product requires it. |

***

### Requesting Additional Models

If you need a model that is not listed, Please fill the form below with following details:

{% embed url="<https://forms.gle/GdPQvonmjWUgZJj3A>" %}

* Model name & version
* Source link or paper reference
* Intended use case and traffic details

Requests are reviewed weekly and prioritised by feasibility and demand.

***

### Current Catalogue Snapshot (July 2025)

| Model                              | Provider     | Type               |
| ---------------------------------- | ------------ | ------------------ |
| chitrapathak                       | Krutrim      | Image-text-to-text |
| Llama-3.2-11B-Vision-Instruct      | Meta         | Image-text-to-text |
| gemma-3-27b-it                     | Google       | Multimodal         |
| Llama-4-Maverick-17B-128E-Instruct | Meta         | Multimodal         |
| Krutrim-Dhwani                     | Krutrim      | Speech-to-Text     |
| DeepSeek-R1-Distill-Llama-70B      | deepseek\_ai | Text-Generation    |
| DeepSeek-R1-Distill-Llama-8B       | deepseek\_ai | Text-Generation    |
| DeepSeek-R1                        | deepseek\_ai | Text-Generation    |
| Krutrim-1                          | Krutrim      | Text-Generation    |
| Krutrim-2                          | Krutrim      | Text-Generation    |
| Llama-3.3-70B-Instruct             | Meta         | Text-Generation    |
| Phi-4-reasoning-plus               | Microsoft    | Text-Generation    |
| Mistral-7B-v0.2                    | MistralAI    | Text-Generation    |
| Qwen3-30B-A3B                      | Qwen         | Text-Generation    |
| Qwen3-32B                          | Qwen         | Text-Generation    |
| Bhasantarit                        | Krutrim      | Text-to-Embedding  |
| Vyakyarth                          | Krutrim      | Text-to-Embedding  |
| Krutrim-TTS                        | Krutrim      | Text-to-Speech     |
| Krutrim-tokenizer                  | Krutrim      | Tokenizer          |

For current pricing and rate limits, see the **Billing** section.

***

### Next Steps

* Continue to **AI Job → Inferencing** to run production jobs.
* Review **Billing** for token accounting and GPU pricing.
* Consult the **API Reference** for full endpoint specifications.

***


# AI Jobs

## AI Jobs

In AI Studio, an **AI Job** is any task that runs on a model—whether you're generating outputs, customizing model behavior, validating performance, or preparing for production use.

Each AI Job uses a specific model version and executes a well-defined operation, with its own inputs, configuration, and outcomes.

***

### Types of AI Jobs

#### 1. Inferencing

Run prompts or inputs through a model to generate outputs.\
Useful for testing, prototyping, or integrating model predictions into your applications.

Learn more → [Inferencing](/basics/ai-studio/ai-jobs/inferencing)

***

#### 2. Fine-Tuning

Train a base model on your domain-specific data using LoRA adapters.\
Produces a customized model that better understands your specific use case or terminology.

Learn more → [Fine-Tuning](/basics/ai-studio/ai-jobs/fine-tuning)

***

#### 3. Evaluation

Measure how well a model performs before deployment.\
AI Studio supports:

* **Model Evaluation** for accuracy and task relevance
* **Performance Evaluation** for latency, throughput, and error rates

Learn more → [Evaluation](/basics/ai-studio/ai-jobs/evaluation)

***

#### 4. Deployment

Turn a model into a production-ready endpoint. We currently support only Finetuned Model deployment. You can choose to deploy it:

* Shared Instance&#x20;
* Dedicated Instance

Learn more →[ Deployment](/basics/ai-studio/ai-jobs/deployment)


# Inferencing

## Inferencing

Once you've identified a model from the Catalog, you can run inference either directly through the Playground or by integrating via API. Inference allows you to generate outputs using prompts, uploaded files, or other input types depending on the model's modality.

***

### 1. How to Run Inference

#### Option 1: Playground (No Code)

Every model in the Catalog includes a **Playground** tab. This UI lets you:

* Enter prompts (for text models)
* Upload files (for speech/image models)
* Adjust generation parameters (`temperature`, `top_p`, `max_tokens`, etc.)
* View results inline

This is the fastest way to test a model before moving to production.

#### Option 2: API via Starter Code

Use the **Starter Code** tab to copy cURL or Python code that calls the Krutrim API directly. The code includes:

* Proper API endpoint
* Pre-filled `model` identifier
* Default prompt structure
* Optional generation parameters

You only need to plug in your API key and input data.

***

### 2. Integration Options

Krutrim inference APIs are **OpenAI-compatible**, making integration seamless with many open-source tools and SDKs.

#### OpenAI SDK (Python)

Krutrim supports the `openai` Python SDK for text models:

{% code overflow="wrap" %}

```python
from openai import OpenAI

client = OpenAI(
    api_key="your_krutrim_key",
    base_url="https://cloud.olakrutrim.com/v1"
)

response = client.chat.completions.create(
    model="krutrim-1",
    messages=[
        {"role": "user", "content": "Explain quantum entanglement simply."}
    ]
)
print(response.choices[0].message.content)
```

{% endcode %}

#### Langchain Integration

Krutrim models can also be used in Langchain through OpenAI-compatible wrappers.

{% code overflow="wrap" %}

```python
/from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(
    openai_api_key="your_krutrim_key",
    openai_api_base="https://cloud.olakrutrim.com/v1",
    model_name="krutrim-1"
)

llm.predict("What are some use cases of LLMs in finance?")

```

{% endcode %}

This enables integration with Langchain chains, memory, tools, and agents.

### 3. Supported Parameters

You can control generation behavior using the following parameters:

<table><thead><tr><th width="184.87890625">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>temperature</code></td><td>Controls randomness (lower = deterministic, higher = more creative)</td></tr><tr><td><code>top_p</code></td><td>Controls nucleus sampling probability mass</td></tr><tr><td><code>max_tokens</code></td><td>Maximum number of tokens to generate</td></tr><tr><td><code>frequency_penalty</code></td><td>Penalizes repeating tokens</td></tr><tr><td><code>presence_penalty</code></td><td>Encourages introducing new topics</td></tr><tr><td><code>logit_bias</code></td><td>Biases probability of specific tokens</td></tr><tr><td><code>stop</code></td><td>Token(s) at which generation should stop</td></tr><tr><td><code>stream</code></td><td>Enables token-by-token streaming</td></tr></tbody></table>

Defaults vary by model and can be overridden via Playground or API.

***

### 4. Tokenization and Output

* Each model uses its own tokenizer, which is applied automatically.
* You are charged per **input + output tokens**, based on the model's pricing.

Refer to the **Billing** page for detailed rates and token limits.

***

### 5. Troubleshooting Inference

| Symptom               | Likely Cause                      | Solution                                         |
| --------------------- | --------------------------------- | ------------------------------------------------ |
| Output is cut off     | `max_tokens` is too low           | Increase the `max_tokens` value                  |
| Output is repetitive  | Low `temperature` or no penalties | Raise `temperature` or apply `frequency_penalty` |
| High latency          | Large model or long prompt        | Use a smaller model or reduce prompt size        |
| Invalid model error   | Incorrect model name              | Copy exact model string from the Model Card      |
| Authentication failed | Missing or expired API key        | Regenerate your API key in the Krutrim Console   |

***

### 6. Next Steps

* Fine-Tune a model for improved domain alignment
* Evaluate model quality and latency metrics
* Deploy a model as a persistent, production-ready endpoint

For API endpoint details and parameters, visit the **API Reference**.


# Fine-tuning

## Fine-Tuning

Fine-tuning allows you to adapt powerful pre-trained models to your own data and domain. This improves output quality, accuracy, and relevance for your specific use case.

AI Studio simplifies the fine-tuning process using efficient adapter-based methods, so you can achieve high-quality customization without the infrastructure complexity.

***

### 1. How Fine-Tuning Works on AI Studio

AI Studio supports fine-tuning via **LoRA (Low-Rank Adaptation)** adapters. These adapters:

* Do not alter the base model weights
* Are faster and cheaper to train
* Enable task-specific customization
* Allow easy rollback or switching between fine-tuned variants

All fine-tuning jobs are run on managed infrastructure with checkpointing and easy deployment built in.

***

### 2. Creating a Fine-Tuning Job

You can create a fine-tuning job from the **Fine-Tuning** section of the console.

#### Step-by-Step

1. **Select a Model**\
   Choose from supported models like Llama-3 or Mistral. Only supported models will appear in the dropdown.
2. **Upload a Dataset**\
   Format must follow the structure below (JSONL or JSON array):

   <pre class="language-json" data-overflow="wrap"><code class="lang-json">{
     "instruction": "Summarize the following text:",
     "input": "Artificial Intelligence is transforming industries...",
     "output": "AI is revolutionizing industries by automating tasks..."
   }
   </code></pre>
3. **Configure Training Parameters**
   * **LoRA Rank**: Controls capacity of the adapter. Higher rank = more detailed adaptation.
   * **Learning Rate**: Default is 1. Lower values are more conservative.
   * **Batch Size**: Default is 8. Tune based on GPU resources.
   * **Checkpointing**: Enable to resume from intermediate points or track progress.
4. **Launch Job**\
   Once configured, submit the job. Resources will be provisioned automatically.

***

### 3. Monitoring Progress

After launching, the console displays real-time metrics:

* Training loss
* Token processed
* Checkpoint status
* Remaining time

Checkpoints are saved periodically and can be used to resume or deploy at any stage.

***

### 4. Deploying the Fine-Tuned Model

Once training is complete:

1. Click **Deploy** from the job page
2. Choose a unique **deployment name**
3. The model will be deployed to a dedicated **NVIDIA H100 GPU** instance
4. Once deployed, it is accessible via the same API structure used for base models

You can manage or terminate deployments to control costs.

***

### 5. Best Practices for Dataset Preparation

* Use high-quality, representative examples
* Avoid noisy or inconsistent entries
* Ensure input-output alignment for each task
* Keep instruction phrasing consistent if possible
* Aim for at least a few hundred examples; more if doing complex generation

***

### 6. Supported Models

Currently supported for fine-tuning:

* **Llama-3-8B-Instruct**
* **Llama-3-8B**
* **Mistral-7B**

{% hint style="info" %}
More models will be added over time.
{% endhint %}

***

### 7. Pricing

Fine-tuning is billed per **1 million tokens processed** during training.

| Model               | Cost per 1M Tokens |
| ------------------- | ------------------ |
| Llama-3-8B-Instruct | ₹33                |

Deployment is billed per GPU-hour:

| Deployment Type  | GPU         | Cost per Hour |
| ---------------- | ----------- | ------------- |
| Fine-tuned Model | NVIDIA H100 | ₹215          |

For cost efficiency:

* Review your dataset before launch
* Use checkpointing to avoid reruns
* Shut down deployments when not in use

***

### 8. Next Steps

* Evaluate your fine-tuned model on benchmark tasks
* Deploy the model for production use
* Review Billing for usage-based pricing and limits
* Consult the API Reference to integrate your fine-tuned model


# Evaluation

## Evaluation

Evaluating a model is critical before taking it to production. Fine-tuned or not, even the most capable models can behave unpredictably without proper testing. Evaluation helps you answer key questions:

* Is this model accurate enough for my task?
* Will it perform well under real-world usage conditions?
* How does it compare with other available models?

AI Studio provides two evaluation types to help you make informed decisions:

***

### 1. Types of Evaluation

| Evaluation Type            | Purpose                                                                                       |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| **Model Evaluation**       | Measures how well the model performs specific tasks using benchmark datasets                  |
| **Performance Evaluation** | Measures runtime behavior including latency, throughput, and error rates under simulated load |

These evaluations serve different goals:

* Use **Model Evaluation** to choose the model most aligned with your use case.
* Use **Performance Evaluation** to validate how the model will behave in production.

You can run either or both, depending on your goals.

***

### 2. Creating an Evaluation Job

#### Step-by-Step

1. Navigate to the **Evaluation** section
2. Click **New Evaluation** and choose the evaluation type
3. Select the **model** and version you want to evaluate
4. Configure task parameters (for Model Evaluation) or load profile (for Performance Evaluation)
5. Click **Run Evaluation**

Evaluation results can be monitored in real time and compared across jobs.

***

### 3. Model Evaluation

This evaluation type focuses on task-specific correctness and relevance. It uses curated public datasets to test the model’s response quality.

#### Supported Task Types

| Task Type              | Datasets                     | Description                                     |
| ---------------------- | ---------------------------- | ----------------------------------------------- |
| Common Sense Reasoning | BoolQ, HellaSwag, PIQA, COPA | Test logical inference over general knowledge   |
| Language Understanding | MMLU                         | Multi-domain comprehension across subjects      |
| Ethicality             | TruthfulQA, WinoGender       | Bias detection and responsible content handling |
| Closed Book QA         | TriviaQA                     | Fact recall without external knowledge sources  |
| Mathematical Reasoning | GSM8k                        | Multi-step numeric reasoning                    |

You can optionally adjust:

* System/User prompts
* Generation hyperparameters (e.g. `temperature`, `max_tokens`, `frequency_penalty`)
* k-shot setting (0, 1, or few-shot examples)

***

### 4. Performance Evaluation

This evaluation simulates production-like traffic to assess the model's latency, throughput, and failure tolerance.

#### Configuration Options

| Parameter                   | Description                            |
| --------------------------- | -------------------------------------- |
| `Test Timeout`              | Max allowed evaluation duration        |
| `Max Completed Requests`    | Number of total calls to simulate      |
| `Concurrent Requests`       | Number of parallel calls (concurrency) |
| `Mean Input Tokens`         | Average size of prompts                |
| `Std. Dev of Input Tokens`  | Variation in input length              |
| `Mean Output Tokens`        | Average number of tokens in output     |
| `Std. Dev of Output Tokens` | Variation in output size               |

#### Metrics Captured

| Metric Type      | Details                                                 |
| ---------------- | ------------------------------------------------------- |
| Latency          | Time-to-first-token, inter-token delay, end-to-end time |
| Throughput       | Requests per second, tokens per second                  |
| Token Accounting | Total tokens processed (input + output)                 |
| Errors           | Failure rate, error codes, timeouts                     |

***

### 5. Comparing Evaluation Jobs

You can compare multiple evaluation runs from the console:

1. Navigate to the **Evaluation** tab
2. Click **Compare**
3. Select multiple jobs of the same type
4. View visual comparison of key metrics

* **Model Evaluation**: Compare task performance side-by-side
* **Performance Evaluation**: Compare latency and throughput under load

This makes it easy to determine whether to switch models, change configuration, or proceed to deployment.

***

### 6. Pricing

Evaluation is charged based on token usage — the same rates as inference.

| Evaluation Type        | Unit                            | Pricing Model       |
| ---------------------- | ------------------------------- | ------------------- |
| Model Evaluation       | Tokens processed during test    | Standard token rate |
| Performance Evaluation | Tokens processed per simulation | Standard token rate |

Note:

* If using a **dedicated deployment**, evaluation jobs run on that instance at no additional cost
* If your balance falls below threshold, evaluation jobs may be paused automatically

***

### 7. Next Steps

* Deploy the model version that performs best
* Fine-Tune if task-level accuracy is still low
* Review Billing for usage rates and quota handling
* Use the API Reference to automate evaluation runs


# Deployment

## Deployment

Once a model is finalized—whether from the Catalog or after fine-tuning—it can be deployed as an always-available endpoint for inference.

AI Studio supports two deployment modes:

* **On-Demand**: Instant, serverless access. Best for quick experiments and lightweight use cases.
* **Dedicated**: Persistent deployment on dedicated infrastructure. Recommended for production-grade workloads.

***

### 1. Why Deploy?

Deploying a model creates a stable, callable API that can be integrated into downstream systems and user-facing products. It ensures:

* Predictable performance
* Repeatable results
* Centralized monitoring
* Easy access via standard APIs

For high-availability, real-time applications, deploying the model is essential.

***

### 2. On-Demand vs Dedicated Deployments

| Mode          | Description                                              | Use Case                                 |
| ------------- | -------------------------------------------------------- | ---------------------------------------- |
| **On-Demand** | Serverless, ephemeral deployment managed by the platform | Ad-hoc testing, internal tools           |
| **Dedicated** | Persistent instance with reserved GPU                    | Production systems, high-throughput APIs |

***

### 3. Why Use Dedicated Deployment?

Dedicated deployments offer significant benefits over serverless access:

* **Guaranteed Throughput**: Your model runs on a dedicated GPU (e.g., NVIDIA H100), delivering consistent latency and handling concurrent requests reliably.
* **Data Security**: Inference runs in an isolated environment, reducing risk of data leakage. Suitable for enterprise, healthcare, and financial use cases.
* **Stable Endpoint**: Model versioning is locked, making it easy to debug, monitor, and iterate. Ideal for applications with audit or compliance needs.
* **Fine-tuned Model Hosting**: Use dedicated deployments to host your own custom fine-tuned models with controlled rollout.

***

### 4. Creating a Deployment

To deploy a model from Model Catalog:

1. Navigate to the deployment tab
2. Click New Deployment
3. Select desired model from drop down
4. Provide unique deplyment name
5. Click on deploy and the system provisions a dedicated instance and exposes an OpenAI-compatible endpoint

To deploy a fine-tuned model:

1. Navigate to the completed fine-tuning job
2. Click **Deploy**
3. Provide a unique deployment name
4. Click on deploy and the system provisions a dedicated instance and exposes an OpenAI-compatible endpoint

Deployment is complete within minutes and ready for use across your application stack.

***

### 5. Managing Deployments

The **Deployments** tab provides:

* **Status Monitoring**: Running, stopped, or failed state
* **Usage Tracking**: Requests, token throughput, and basic logs
* **Deployment Controls**: Start, stop, or redeploy models
* **Checkpoint Selection**: Redeploy older fine-tuning checkpoints if needed

Stopping a deployment releases its GPU and suspends the associated endpoint.

***

### 6. Next Steps

* Run Inference using the deployed model
* Evaluate latency and runtime performance post-deployment
* Fine-Tune to improve domain alignment before deployment
* Refer to the API Reference to integrate your deployment endpoint


# Billing for AI Studio

Krutrim Cloud's **AI Studio** offers access to a diverse catalogue of open-source and in-house AI models for text generation, embeddings, speech, and multimodal use cases. All models are billed **based on usage**, with costs varying depending on the type of input/output and the model in use.

***

### Model catalog billing

Each model in AI Studio defines:

* **Billing mode** (Input tokens, Output tokens, Audio minutes, etc.)
* **Unit of pricing** (Per 1M tokens, Per minute, Per hour, etc.)
* **Rate** (in ₹)

You are billed **only for what you use**. Charges are calculated based on usage metrics collected during API calls or console interactions with the models.

***

### Model Catalog Pricing

| Model Name                                    | Input Rate (₹)     | Output Rate (₹)    | Unit Type        | Task Type            |
| --------------------------------------------- | ------------------ | ------------------ | ---------------- | -------------------- |
| **DeepSeek-R1-Distill-Llama-70B**             | ₹10.00 / 1M tokens | ₹10.00 / 1M tokens | Tokens           | Text Generation      |
| **DeepSeek-R1-Distill-Llama-8B**              | ₹3.00 / 1M tokens  | ₹3.00 / 1M tokens  | Tokens           | Text Generation      |
| **DeepSeek-R1**                               | ₹11.00 / 1M tokens | ₹16.00 / 1M tokens | Tokens           | Text Generation      |
| **Google / Gemma-3-27b-it**                   | ₹8.00 / 1M tokens  | ₹25.00 / 1M tokens | Tokens           | Multimodal           |
| **Krutrim / Krutrim-1**                       | ₹16.6 / 1M tokens  | ₹16.6 / 1M tokens  | Tokens           | Text Generation      |
| **Krutrim / Krutrim-2**                       | ₹6.6 / 1M tokens   | ₹6.6 / 1M tokens   | Tokens           | Text Generation      |
| **Krutrim / Krutrim-TTS**                     | N/A                | ₹4.42 / min        | Minutes (output) | Text-to-Speech       |
| **Krutrim / Krutrim-Dhwani**                  | ₹24.00 / hour      | N/A                | Hours (input)    | Speech-to-Text       |
| **Krutrim / Bhasantarit**                     | ₹6.26 / 1M tokens  | N/A                | Tokens (input)   | Text-to-Embedding    |
| **Krutrim / Vyakyarth**                       | ₹6.06 / 1M tokens  | N/A                | Tokens (input)   | Text-to-Embedding    |
| **Krutrim / Chitrapathak**                    | ₹83.6 / 1M tokens  | ₹34.53 / 1M tokens | Tokens           | Image-to-Text        |
| **Krutrim / Tokenizer**                       | ₹0.00              | ₹0.00              | Tokens           | Tokenization Utility |
| **Meta / LLaMA-3.2-11B-Vision-Instruct**      | ₹14.94 / 1M tokens | ₹14.94 / 1M tokens | Tokens           | Image-to-Text        |
| **Meta / LLaMA-3.3-70B-Instruct**             | ₹73.04 / 1M tokens | ₹73.04 / 1M tokens | Tokens           | Text Generation      |
| **Meta / LLaMA-4-Maverick-17B-12BE-Instruct** | ₹17.00 / 1M tokens | ₹50.00 / 1M tokens | Tokens           | Multimodal           |
| **Microsoft / Phi-4 Reasoning Plus**          | ₹5.00 / 1M tokens  | ₹29.00 / 1M tokens | Tokens           | Text Generation      |
| **Mistral / Mistral-7B-v0.2**                 | ₹16.6 / 1M tokens  | ₹16.6 / 1M tokens  | Tokens           | Text Generation      |
| **Qwen / Qwen3-32B**                          | ₹8.00 / 1M tokens  | ₹25.00 / 1M tokens | Tokens           | Text Generation      |
| **Qwen / Qwen3-30B-A3B**                      | ₹8.00 / 1M tokens  | ₹25.00 / 1M tokens | Tokens           | Text Generation      |

***

### Additional Notes

* **Tokenization logic** varies by model and is handled automatically using the model’s default tokenizer.
* **Speech models** are priced per **minute/hour of audio**, based on the type (TTS or STT).
* **Multimodal models** may count both text and vision tokens.

***

### Evaluation Billing

The cost of running **Model Evaluations** and **Performance Evaluations** on the Krutrim platform is the **same as inference** — based on the number of tokens processed.

#### Token-Based Pricing

* You are billed per token used during evaluation.
* There are **no additional fees** for launching or running evaluation jobs.

#### Low Balance Handling

* If your account balance drops below a certain threshold, the platform will **automatically pause evaluation services** until funds are added.

### Fine-Tuning Billing

Krutrim offers transparent and flexible pricing for both **fine-tuning** and **deployment** of custom models. Below is a detailed breakdown of the billing model:

#### Fine-Tuning Pricing

Fine-tuning costs are calculated **per 1 million tokens**, and pricing varies based on the model used.

| Model               | Price (INR) | Unit          |
| ------------------- | ----------- | ------------- |
| Llama-3-8b-instruct | ₹33         | per 1M tokens |

> **Note:** This is **token-based pricing**, ensuring you pay only for the compute resources used during fine-tuning.

***

#### Deployment Pricing

Once your model is fine-tuned, you can deploy it on an **NVIDIA H100 GPU**. Pricing is based on actual GPU usage.

| GPU Resource | Price (INR) | Unit         |
| ------------ | ----------- | ------------ |
| NVIDIA H100  | ₹213        | per GPU-hour |

> Deployment pricing **includes inference usage** — you are charged only for the **active duration** of your deployment.

***

#### Cost Management Best Practices

* **Optimize Your Dataset**: High-quality, concise datasets reduce token usage and improve training efficiency.
* **Monitor Active Deployments**: Shut down unused deployments to avoid incurring extra GPU charges.
* **Use Checkpoints**: Save checkpoints during training to avoid repeating the entire process in case of interruptions.

***

#### Low Balance Handling

If your account balance falls below a defined threshold:

* **Fine-tuning and deployment services will be automatically paused.**
* Resume once sufficient balance is added to the account.

### Where to See This in Console

To see real-time usage and billing:

1. Go to **Billing → Usage → AI Studio**
2. Select the relevant sub-tab:
   * **Model Catalogue**
   * **Fine Tuning**
   * **Deployment**
   * **Evaluation**
3. Use the **date filter** to narrow your view
4. Click **Export** to download usage data


# AI Solutions

## AI Solutions – Overview

Krutrim Cloud offers **AI Solutions** designed to address high-impact, domain-specific use cases by combining cutting-edge AI models with optimized infrastructure.\
These solutions go beyond general-purpose APIs by providing specialized capabilities for tasks such as **multilingual speech processing**, **document intelligence**, and **enterprise-grade automation**.

Currently, Krutrim Cloud offers the following AI Solutions:

***

### **1. Bhashik – Indic Language Speech Processing**

**Bhashik** is an AI-powered speech model developed by Krutrim for **vernacular Indian language** support.\
It is optimized for **Text-to-Speech (TTS)** and **Speech-to-Text (STT)**, enabling developers to build applications in local languages without sacrificing accuracy or performance.

**Key Features:**

* **Text-to-Speech (TTS):** Convert text into natural-sounding speech in supported Indic languages.
* **Speech-to-Text (STT):** Transcribe audio input into accurate, structured text.
* **Multilingual & Vernacular Focus:** Supports multiple Indian languages for voice-based applications.
* **Use Cases:**
  * Interactive voice assistants in regional languages
  * Voice-enabled customer service
  * Accessibility tools for local language users
  * Media transcription and dubbing workflows

***

### **2. DIS – Document Intelligence Services**

**Document Intelligence Services (DIS)** is a suite of AI-powered document processing capabilities.\
It enables automated extraction, analysis, and transformation of information from structured and unstructured documents.

**Key Features:**

* **Text Extraction:** Retrieve raw text from document files.
* **Information Extraction:** Identify entities, key-value pairs, and personally identifiable information (PII).
* **Document Summarization:** Generate concise summaries of lengthy documents.
* **PII Masking:** Automatically mask sensitive information to maintain compliance.
* **Asynchronous Processing:** Submit documents via API and retrieve results without blocking.
* **Use Cases:**
  * Automating KYC document processing
  * Legal document summarization
  * Data entry automation
  * Privacy-compliant document sharing


# Bhashik

**Bhashik** is Krutrim’s advanced Indic AI model, purpose-built for **vernacular speech and text processing**. It is optimized for **Text-to-Speech (TTS)** and **Speech-to-Text (STT)** use cases across multiple Indian languages, enabling natural, context-aware communication for diverse regional audiences.

Bhashik powers a wide range of capabilities for both text and speech workflows, making it ideal for building applications such as voice assistants, multilingual customer support, automated transcription, and real-time translation.

### **Capabilities**

#### **Text-based AI Services**

* **Text Translation** – Translate written content between multiple languages with high accuracy and cultural nuance.
* **Language Detection** – Automatically identify the language present in a given text snippet.
* **Entity Extraction** – Identify and extract specific data points or entities from text for structured analysis.
* **Sentiment Analysis** – Detect the overall sentiment of content or the sentiment toward a specific entity.
* **Summarization** – Condense long text into concise summaries while preserving meaning.

#### **Speech-based AI Services**

* **Text to Speech (TTS)** – Convert written text into natural-sounding speech across multiple Indian languages.
* **Speech to Text (STT)** – Transcribe audio into text accurately, making it easy to record and analyze spoken content.
* **Speech to Speech** – Translate spoken language directly into another language, enabling fluid, multilingual conversations.

### **Key Advantages of Bhashik**

* **Vernacular-first Approach** – Built to natively support Indian languages and dialects.
* **Multi-modal Support** – Seamless integration across both text and speech processing tasks.
* **High Accuracy** – Optimized for real-world scenarios such as noisy environments and regional pronunciations.
* **Customizable** – Can be fine-tuned or adapted for domain-specific vocabulary and context.


# Document Intelligence Service

The **Document Intelligence Services** in Krutrim Cloud offer a comprehensive suite of AI-powered tools for **document processing, information extraction, and data privacy**. These services enable businesses and developers to automate the reading, understanding, and transformation of documents at scale.

With capabilities such as **text extraction, entity recognition, key-value pair detection, document summarization, and PII masking**, you can turn unstructured documents into structured, actionable insights while ensuring sensitive information is protected.

### **How It Works**

The **Document Processing API** operates asynchronously for efficiency and scalability:

1. **Submit a Document** – Upload the file via the Document API.
2. **Receive a fileId** – A unique `fileId` is generated to track your request.
3. **Check Processing Status** – Use the Status API to verify if processing is complete.
4. **Retrieve Results** – Once processing finishes, download the processed output from the provided link.

This approach allows you to submit documents without waiting for real-time processing, making it ideal for high-volume workloads.

### **Available Services**

* **Extract Text** – Pull raw text content from documents, scanned files, and images.
* **Extract Information** – Identify and extract structured details, including:
  * **PII** (Personally Identifiable Information)
  * **NER** (Named Entity Recognition)
  * **Key-Value Pairs**
* **Document Summarization** – Generate concise summaries that preserve the key points of the original content.
* **PII Masking** – Mask or obfuscate sensitive personal information to ensure compliance with privacy regulations.

### **Authentication & Rate Limits**

* **API Keys** – Required for all API requests. API keys can be generated and managed in the [**KMS (Key Management System)**](https://docs.cloud.olakrutrim.com/~/revisions/R3YmuRbo1BQTbXR88xJJ/basics/key-management-system/model-api-keys).
* **Rate Limits** – Default limit of **20 requests per minute (RPM)** to ensure fair usage.


# Billing For AI Solutions

Krutrim Cloud’s AI Solutions offer access to powerful APIs across **text, speech, and document intelligence**.\
All APIs are billed on a **pay-as-you-go** basis, with costs depending on the **type of input** (characters, audio hours, or pages processed).

You are billed only for what you use. Charges are calculated automatically based on API usage recorded during calls made through the console or SDK.

***

### Bhashik Billing

Bhashik provides a suite of text and speech APIs for tasks such as language detection, translation, summarization, and speech recognition.

#### Pricing Summary

| Category            | API Name                                   | Unit                  | Rate (₹) |
| ------------------- | ------------------------------------------ | --------------------- | -------- |
| **Text Services**   | Language Detection                         | 1M input characters   | ₹66      |
|                     | Entity Extraction                          | 1M input characters   | ₹66      |
|                     | Summarization                              | 1M input characters   | ₹66      |
|                     | Translation                                | 1M input characters   | ₹581     |
|                     | Sentiment Analysis                         | 1M input characters   | ₹66      |
| **Speech Services** | Text-to-Speech                             | 1M input characters   | ₹266     |
|                     | Speech-to-Text                             | 1 hour of input audio | ₹24      |
|                     | Text-to-Speech Translation                 | 1M input characters   | ₹1262    |
|                     | Speech-to-Text Translation                 | 1 hour of input audio | ₹24      |
|                     | Speech-to-Speech Translation               | 1 hour of input audio | ₹166     |
|                     | Speech-to-Text (Long Duration)             | 1 hour of input audio | ₹24      |
|                     | Speech-to-Text Translation (Long Duration) | 1 hour of input audio | ₹24      |

#### Example Calculations

```
Example 1:
Summarization of 250,000 characters → (0.25 × ₹66) = ₹16.50

Example 2:
Speech-to-Text of 20-minute audio → (0.33 hr × ₹24) = ₹7.92

Example 3:
Translation of 1M characters → ₹581 total
```

***

### DIS Billing

Document Intelligence Services (DIS) enable OCR, text extraction, information extraction, summarization, and PII masking across images and documents.

#### Pricing Summary

| API Name            | Unit                 | Rate (₹) |
| ------------------- | -------------------- | -------- |
| Extract Text        | OCR: per 1,000 pages | ₹398     |
|                     | Doc: per 1,000 pages | ₹100     |
| Extract Information | OCR: per 1,000 pages | ₹1,726   |
|                     | Doc: per 1,000 pages | ₹1,726   |
| Summarisation       | OCR: per 1,000 pages | ₹531     |
|                     | Doc: per 1,000 pages | ₹166     |
| PII Masking         | Doc: per 1,000 pages | ₹232     |

***

#### Example Calculations

```
Example 1:
Extract Text (OCR) for 200 pages → (0.2 × ₹398) = ₹79.60

Example 2:
Example Summarisation (Doc) for 500 pages → (0.5 × ₹166) = ₹83.00
```

***

### Additional Notes

* All prices are **exclusive of taxes**.
* Partial usage (characters, minutes, or pages) is **prorated** automatically.
* Bhashik APIs bill on **input size**, regardless of output length.
* Long-duration STT APIs return a `request_id` for queued jobs but follow the same per-hour pricing.

### Where to See This in Console

To track usage and billing for AI Solutions:

1. Navigate to **Billing → Usage → AI Solutions** in the Krutrim Console.
2. Select a product tab — **Bhashik** or **DIS**.
3. Use filters to view usage by date or API.
4. Click **Export** to download usage data.


# Certificate Manager

### Overview

Krutrim Cloud **Certificate Manager** allows you to securely **store, manage, and attach SSL/TLS certificates** to your Krutrim cloud resources. Certificates ensure encrypted communication between your applications and end users, improving security and trust.

At present, Certificate Manager supports attaching certificates to **Load Balancers**. In future, support will be extended to other services such as CDN, API Gateway, and custom domain integrations.

Key capabilities include:

* Upload and centrally manage SSL/TLS certificates.
* Attach uploaded certificates to supported Krutrim Cloud resources.
* Update or replace expiring certificates without disrupting attached resources.

### Using Certificate Manager in Krutrim Cloud Console

#### 1. Navigate to Certificate Manager

* Sign in to your **Krutrim Cloud Console**.
* From the left navigation pane, go to **Administration → Certificate Manager**.
* The Certificate Manager dashboard lists all certificates uploaded.

#### 2. Upload a Certificate

* Click on **Upload Certificate**.
* Provide a descriptive **Name** for your certificate.
* Upload the required certificate files in .p12 format.
* If your certificate file is password-protected, please also provide the certificate password to allow read access.
* *(Optional)* Add **tags** (for example: `prod`, `staging`, `web-app`) to easily group and filter certificates later.
* Click **Upload Certificate** button to upload.
* Once uploaded, the certificate will appear in the list view with status **Active**.
* From the dashboard, you can view certificate details such as name, primary domain, expiry date and action button menu with options of **View Details, Update Certificate** and **Delete.**

#### 3. Update an Existing Certificate

If your certificate is expiring or needs renewal:

* Go to **Certificate Manager → Select Certificate → Update Certificate**.
* Upload the new **certificate file** and its corresponding **password**, if applicable.
* Optionally update **Certificate Name** or **tags**.
* Once updated, all associated resources (e.g., Load Balancers) will automatically start using the renewed certificate without reattachment.

#### 4. Attach a Certificate to Load Balancer

* From the left navigation pane navigate to your **Load Balancer** service in the console.
* While creating or editing a Load Balancer, go to the **Listener Configuration** section.
* Under **SSL** **Certificate**, choose an existing certificate from the dropdown list.
* Save or update the Load Balancer configuration.
* Once attached, SSL termination for your Load Balancer will be handled using the selected certificate.

#### 5. Detach or Delete a Certificate

* To detach, open the associated Load Balancer configuration and remove the certificate.
* To delete a certificate:
  * Go to **Certificate Manager → Select Certificate → Delete**.
  * If the certificate is **currently attached to any resources**, deletion will be blocked.
  * In this case, the **Delete modal** provides a **CTA button** that redirects you to the associated resource(s) page. You can detach the certificate there, and then return to Certificate Manager to delete it.
* Deletion is irreversible and the certificate cannot be recovered once deleted.

### Notes

* Supported file formats: `.p12`
* Maximum file size: **64 KB** per certificate file
* Certificates must be **valid and not expired** at the time of upload
* Tags can be used to organise certificates by environment, application, or purpose


# Key Management System

The **Key Management System (KMS)** in Krutrim Cloud is the central hub for creating and managing cryptographic keys that enable secure access to your resources. It simplifies credential management while ensuring best practices for security and access control.

KMS supports multiple key types for different use cases:

* **SSH Keys** – For secure, password-less access to your virtual machines.
* **API Keys for Model Access** – For calling Krutrim’s model APIs.
* **Bucket API Keys** – For programmatically accessing and managing your storage buckets.

By consolidating these capabilities into one service, Krutrim Cloud enables developers, researchers, and enterprises to securely manage access to their compute, storage, and AI services in a single location.


# Accessing Buckets

## Creating a Key for Accessing Buckets in Object Storage

To access buckets in Krutrim Cloud’s **Object Storage**, you need to generate an API key using the Key Management Service (KMS). Follow the steps below to create and securely store your key.

***

### Steps to Create a Bucket API Key

1. **Navigate to KMS**
   * From the Krutrim Cloud Console, go to the **Key Management Service** section.
2. **Go to the Storage Section**
   * Inside KMS, select the **Storage** tab to view storage-related key options.
3. **Create a Bucket API Key**
   * Click on **Create Bucket API Key** to start the key generation process.
4. **Select Region**
   * Choose the region where your bucket resides.
   * This ensures the generated key will have access to buckets in that region.
5. **Create Key**
   * Click **Create** to generate your new API key.
6. **Retrieve Public and Private Keys**
   * Once created, you will be shown a **Public Key** and a **Private Key**.

{% hint style="warning" %}
The **Private Key** will only be displayed once.

* Copy and store it in a secure location immediately.
* Losing this key means you will have to generate a new one.
  {% endhint %}

***

### Usage

* Use the **Private Key** along with the **Public Key** to authenticate and access your buckets in Block Storage via APIs or SDKs.
* Ensure your private key is never exposed in public code repositories or logs.

***

**Security Best Practices**

* Store your private key in a secure password manager or encrypted vault.
* Rotate keys periodically for enhanced security.
* Revoke unused keys from the KMS to reduce exposure risks.


# Model API Keys

To use Krutrim's model APIs or fine-tuning features, you must create a secure API key via the **Key Management System (KMS)**. Follow the steps below to generate and manage your API keys safely.

***

### Steps to Create an API Key

1. **Navigate to KMS:**
   * Log in to the Krutrim Console.
   * In the left-hand sidebar, click on **KMS** (Key Management System).
2. **Go to the Model Section:**
   * Within the KMS dashboard, click on the **Model** tab.
   * This section allows you to create and manage API keys specifically for model access.
3. **Click on "Create API Key":**
   * You will see a button labeled **Create API Key**.
   * Click this to open the API Key creation form.
4. **Enter a Secret Name:**
   * Provide a meaningful name for the API key.\
     For example: `production-key`, `test-env`, or `fine-tune-llama3`.
5. **Generate and Copy the API Key:**
   * Once the key is generated, **copy it immediately** and store it securely.
   * You will not be able to view the key again after closing the dialog.

***

### &#x20;Important Notes

* **Security Best Practice:** Store your API keys in environment variables or secret managers. Avoid hard-coding them into your source code.
* **Scope Limitation:** Each API key is scoped to a specific model group. Use separate keys for production and testing environments when possible.
* **Key Rotation:** Periodically delete and regenerate your API keys to maintain security.

***

### &#x20;Example Usage (with cURL)

```bash
curl https://cloud.olakrutrim.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your secret key here>" \
  -d '{
    "model": "Meta-Llama-3-8B-Instruct",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
```

***

### Revoking or Managing Keys

To revoke or rotate an API key:

1. **Go back to the KMS > Model tab.**
2. **Find the API key** you want to manage from the list of existing keys.
3. Click on **Delete** icon to revoke the key.

***

By following this process, you can securely generate and manage API keys for all your **model** workflows on the Krutrim platform.


# SSH Access for VMs

SSH Keys are used to securely access your VMs

### Creating an SSH Key

1. Go to the SSH Key section under Key management service
2. Click on "Create Key"
3. Select the region in which you want the VM to be present
4. Enter a name for the key
5. Paste the public key. Learn how to create the key from [here](https://krutrim-cloud-documentation.gitbook.io/krutrim-cloud-documentation/~/revisions/JtujsKCePLeIgdxgLhGC/basics/core-infrastructure/compute/ssh-key).
6. Click on "Create key"
7. Your SSH Key will be created, and you can use it with your VMs

### Rotating keys

If your SSH key has been inactive (Not attached to any VMs) for more than 3 months, then it will expire. You will have to rotate the key

1. Go to the SSH Key section under Key management service
2. Click on the action button near your expired key
3. Paste the new public key. Learn how to create the key from [here](https://krutrim-cloud-documentation.gitbook.io/krutrim-cloud-documentation/~/revisions/JtujsKCePLeIgdxgLhGC/basics/core-infrastructure/compute/ssh-key).
4. Click on "Rotate key"
5. Your SSH Key will be rotated, and you can use it with your VMs


# Usage and Transactions

### **Usage**

The **Usage** sections i Krutrim Cloud provides a unified view of your resource consumption, costs, and transaction history. It enables you to track credits usage across all services, review your remaining balance, and manage payment records — ensuring complete transparency over your cloud spending.

### **Usage Metrics**

The **Usage Metrics** dashboard helps you monitor how your credits are being consumed across various Krutrim Cloud services, including:

* **Core Infrastructure** – Compute, Storage, Network
* **AI Studio** – Model Catalogue, Deployment, Finetuning, Evaluation
* **AI Solutions** – Bhashik, DIS, Industrial Solutions

#### **Key Features**

* **Remaining Balance**: Shows the available credits for use.
* **Total Credits Used**: Displays cumulative usage within a selected date range.
* **Breakdown by Service**: Visual representation of credits consumed by each service.
* **Time Filter**: Select a specific date range to analyse historical usage trends.

***

### **Transactions**

The **Transactions** section provides detailed records of your payments, credit top-ups, and service charges, allowing you to manage finances effectively.

#### **Key Features**

* **Transaction History**: Complete list of all payments, credit purchases, and refunds.
* **Transaction Details**: Includes ID, date & time, type (service payment or credit purchase), description, service category, amount, and status.
* **Actions**:
  * **View Details** – See complete transaction information.
  * **Download Receipt** – Save a copy for your records.
* **Status Indicators**:
  * *Completed* – Payment successfully processed.
  * *Pending* – Transaction awaiting confirmation.
  * *Failed* – Payment attempt unsuccessful.
  * *Refunded* – Credits refunded to your account.

***

### **How They Work Together**

* **Usage Metrics** tells you *where* your credits are being spent.
* **Billing** tells you *how* and *when* you purchased or spent credits.

Together, these sections give you **end-to-end visibility** over your cloud usage and costs, helping you plan and optimise your consumption.


# Adding Credits

To use Krutrim Cloud services, you need to maintain a credit balance in your account. Credits are consumed as you use infrastructure, AI models, or managed solutions. You can top up your balance at any time using the **Add Credits** option from the console.

***

#### How to Add Credits

1. **Click on your balance** at the top-right corner of the console.
2. Select **“Add Credits.”**
3. **Enter the amount** you wish to add (in ₹).
4. The system will show the **total bill including GST (18%)**.
5. Complete the payment via **card or UPI** (processed through Razorpay).

***

#### Notes

* **1 INR = 1 Credit**
* Credits are added instantly upon successful payment.
* Billing follows Indian tax norms with **18% GST** added to the base amount.


# Billing Models

Krutrim Cloud offers two flexible billing models to support a wide range of user needs—from rapid, on-demand provisioning to long-term enterprise-scale deployments. These models are designed to provide transparency, cost-efficiency, and flexibility for both individual developers and large organizations.

***

### 1. Pay-as-You-Go (On-Demand Billing)

The **Pay-as-You-Go** model allows you to provision and use cloud services instantly, with billing based on actual usage time.

#### Key Highlights:

* **No upfront commitment**
* **Instant provisioning** of compute, storage, and other services
* **Per-unit pricing** clearly visible on the Krutrim Cloud Console
* **Billing is time-based**, typically metered by the hour or per GB (depending on service)

You are charged only for the duration your resources are active. Once you stop or delete the resource, billing stops automatically.

{% hint style="info" %}
This model is ideal for developers, startups, or teams running short-term, burstable workloads.
{% endhint %}

***

### 2. Enterprise Usage (Committed Billing)

The **Enterprise Usage** model is tailored for organizations with predictable or large-scale requirements. It allows you to commit to a defined volume of usage over time in exchange for custom pricing and additional benefits.

#### Key Highlights:

* **Custom bundles and rates** based on your usage profile
* **Dedicated support** and technical onboarding
* **Works well for production workloads, research teams, and AI labs**

To explore enterprise pricing, reach out to our team at ***<sales@olakrutrim.com>***

We will work with you to understand your workloads and provide a tailored quote that maximizes performance and cost-efficiency.

***

### Which Model Should You Choose?

| Use Case                                    | Recommended Model |
| ------------------------------------------- | ----------------- |
| Experimenting with VMs or AI models         | Pay-as-You-Go     |
| Unpredictable or bursty workloads           | Pay-as-You-Go     |
| Production deployment of AI pipelines       | Enterprise Usage  |
| Dedicated GPU clusters or multi-team access | Enterprise Usage  |


# Identity Access Management

## Identity Access Management (IAM)

Krutrim Cloud Identity Access Management (IAM) controls **who can access what** within an organization using a **Role-Based Access Control (RBAC)** model.

IAM is designed to be **secure by default**, **deterministic**, and **extensible**.

***

### How IAM Works

IAM permissions flow through four entities:

* **Users** → human identities
* **Policies** → permission rules
* **Roles** → collections of policies
* **Groups** → collections of roles

```
Policy → Role → (User | Group) → User
```


# Users

Users represent **human identities** that can access Krutrim Cloud resources.\
All access granted to a user is evaluated through **roles and groups**.

{% hint style="info" %}
Users never receive permissions directly. Permissions are always inherited via roles
{% endhint %}

***

### User Types

#### Root User

* Created during account sign-up
* Owner of the account
* Can manage all IAM entities
* Cannot be modified or deleted by other users

#### IAM User

* Invited by the root user or an authorized admin
* Has scoped permissions
* Can have console access, programmatic access, or both

{% hint style="warning" %}
One email address can be associated with **only one root user**, but may be used for multiple IAM users across different organizations.
{% endhint %}

***

### Adding a User

Adding a user is a **two-step flow**:

1. Enter user details
2. Assign roles and/or groups

Only the **root user** or users with appropriate IAM permissions can add new users.

***

#### Step 1: Enter User Details

Navigate to **IAM → Users** and click **Add User**.

Fill in the following fields:

1. **Email**
   1. Email address of the user being invited
   2. Used as the login identifier
2. **Username**
   1. Unique username within the organization
   2. Used for display and identification
3. **Generated Password**
   1. System-generated temporary password
   2. Cannot be manually edited
   3. Can be:
      1. Regenerated using the refresh icon
      2. Copied using the copy icon

Click **Next** to continue.

***

#### Step 2: Assign Roles and Groups

In this step, you assign **how the user gets permissions**.

1. **Assign Roles**
   1. Select one or more roles to attach directly to the user
   2. Search is available to quickly find roles
2. Each role shows:
   1. Role name
   2. Short description
3. **Assign Groups**&#x20;
   1. Switch to the **Groups** tab
   2. Select one or more groups
   3. The user will inherit all roles attached to those groups

{% hint style="info" %}
At least one role or group must be assigned
{% endhint %}

Click **Send Invitation** to complete the process.

***

### What Happens After Invitation

* The user receives an email with:
  * Organization ID
  * Login email
  * Preset password
* We recommend that the user reset their password after logging in for the 1st time.
* Permissions are enforced immediately after login.


# Policies

### What Is a Policy?&#x20;

A policy defines what actions are allowed or denied on which resources in Krutrim Cloud.

Policies are written as JSON documents containing permission rules (called statements). A policy does not grant access by itself—it only takes effect when attached to a role.

Key Characteristics

* Policies cannot be attached directly to users or groups
* Policies have no effect without roles
* All permission evaluation happens at the role level
* Users get access only through roles/groups

### Policy Rule Model

Every policy follows a structured rule model.

#### Core Policy Fields

| Field        | Description                                                                                                                                                                                                         | Required |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| Policy Name  | Unique identifier for the policy                                                                                                                                                                                    | Yes      |
| Description  | Purpose of the policy                                                                                                                                                                                               | Yes      |
| Access Rules | <p>Each policy consists of one or more rules with the following fields:<br>Policy Type: Service or capability namespace<br>Operations: Usually CRUD<br>Effect: Allow / Deny<br>Resource Name:Resources affected</p> | Yes      |

#### Access Rule Fields

| Field          | Description               | Example                                                                                                                                                                                                                                                                                             |
| -------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Policy Type    | Target cloud service      | All, Security Group, VPC, Virtual machine, Krutrim Certificate Manager, Krutrim Block Storage, Krutrim Object Storage, DNS, Krutrim Kubernetes System, Auto Scaling Groups, Load Balancer, Krutrim Ai Pods, Finetuning, Evaluation, IAM, Model Registry, DBaaS, MaaS, Inference, Billing, SSH Keys. |
| Resource  Name | Resources affected        | set to \* by default)                                                                                                                                                                                                                                                                               |
| Operations     | Allowed or denied actions | Create, Read, Update and Delete                                                                                                                                                                                                                                                                     |
| Effect         | Permission outcome        | Allow or Deny                                                                                                                                                                                                                                                                                       |

<br>

Allow vs. Deny Logic

* Allow → Grants permission
* Deny → Explicitly blocks permission

Evaluation Order:

1. Deny statements are evaluated first
2. If any deny matches → access is blocked
3. If no deny matches → allow statements are evaluated
4. If no allow matches → access is denied by default

&#x20;Important: Deny always overrides allow.

***

### Policy Creation Flow

1. Define policy (name, description)
2. Specify Access Rule (service, resource, operation, effect)
3. Save the policy
4. Attach policy to role(s)
5. Assign role to users or groups

&#x20;Note: A policy has no effect until attached to a role.

***

### Managing Policies

#### Editing a Policy

You can edit a policy to:

* Update name or description
* Add, Remove or Modify statements
* remove conditions

Steps:

1. IAM → Policies
2. Select policy → Edit
3. Make changes → Save

Editing a policy immediately affects:

* All roles using the policy
* All users assigned to those roles (directly or via groups)

Changes may:

* Grant new access
* Revoke existing access
* Change / Break user workflows

Best Practices:

* Communicate changes in advance
* Review attached roles before editing
* Avoid frequent edits to widely-used policies
* Prefer creating new policies instead

#### Deleting a Policy

Policies cannot be deleted while attached to roles.

Steps:

1. Detach policy from all roles
2. Return to policy
3. Click Delete

&#x20;Warning: Deletion is permanent.

***

### Policy Types by Service

Policies are organized by service and by access level.

#### Default (System-Managed) Policies

Krutrim Cloud provides predefined policies for common use cases.

| Policy Type     | Description                   |
| --------------- | ----------------------------- |
| FullAccess      | Full control over the service |
| ReadAccess      | Read Only access              |
| ReadWriteAccess | Read and modify (no delete)   |

Characteristics:

* Created and maintained by the system
* Cannot be edited or deleted
* Evaluated like regular policies

<details>

<summary><strong>List of Default Policies</strong></summary>

<table data-header-hidden><thead><tr><th width="168.73046875">Service Name</th><th>Policy Name</th><th>Description</th><th>Resources</th></tr></thead><tbody><tr><td>asg</td><td>KASGFullAccess</td><td>Krutrim ASG Full Access Policy</td><td>Auto-Scaling Groups</td></tr><tr><td>asg</td><td>KASGReadOnlyAccess</td><td>Krutrim ASG Read Only Access Policy</td><td>Auto-Scaling Groups</td></tr><tr><td>asg</td><td>KASGReadWriteAccess</td><td>Krutrim ASG Read Write Access Policy</td><td>Auto-Scaling Groups</td></tr><tr><td>billing</td><td>KBillingFullAccess</td><td>Krutrim Billing Full Access Policy</td><td>Billing</td></tr><tr><td>dbaas</td><td>KDBaaSFullAccess</td><td>Krutrim DBaaS Full Access Policy</td><td>DBaaS</td></tr><tr><td>dbaas</td><td>KDBaaSReadOnlyAccess</td><td>Krutrim DBaaS Read Only Access Policy</td><td>DBaaS</td></tr><tr><td>dbaas</td><td>KDBaaSReadWriteAccess</td><td>Krutrim DBaaS Read Write Access Policy</td><td>DBaaS</td></tr><tr><td>dns</td><td>KDNSFullAccess</td><td>Krutrim DNS Full Access Policy</td><td><p>DNS, </p><p>Zones, </p><p>Records</p></td></tr><tr><td>dns</td><td>KDNSReadOnlyAccess</td><td>Krutrim DNS Read Only Access Policy</td><td><p>DNS, </p><p>Zones, </p><p>Records</p></td></tr><tr><td>dns</td><td>KDNSReadWriteAccess</td><td>Krutrim DNS Read Write Access Policy</td><td><p>DNS, </p><p>Zones, </p><p>Records</p></td></tr><tr><td>evaluation</td><td>KEvaluationFullAccess</td><td>Krutrim Evaluation Full Access Policy</td><td>Evaluation</td></tr><tr><td>evaluation</td><td>KEvaluationReadOnlyAccess</td><td>Krutrim Evaluation Read Only Access Policy</td><td>Evaluation</td></tr><tr><td>evaluation</td><td>KEvaluationReadWriteAccess</td><td>Krutrim Evaluation Read Write Access Policy</td><td>Evaluation</td></tr><tr><td>finetuning</td><td>KFineTuningFullAccess</td><td>Krutrim Fine Tuning Full Access Policy</td><td>Fine-Tuning</td></tr><tr><td>finetuning</td><td>KFineTuningReadOnlyAccess</td><td>Krutrim Fine Tuning Read Only Access Policy</td><td>Fine-Tuning</td></tr><tr><td>finetuning</td><td>KFineTuningReadWriteAccess</td><td>Krutrim Fine Tuning Read Write Access Policy</td><td>Fine-Tuning</td></tr><tr><td>iam</td><td>KIAMFullAdminAccessAllResources</td><td>Krutrim Centralized IAM Full Access Policy across all IAM resources</td><td><p>Users, </p><p>Groups, </p><p>Roles, </p><p>Policies, </p><p>Association Between Users/Groups/Roles/Policies</p></td></tr><tr><td>iam</td><td>KIAMReadOnlyAccessAllResources</td><td>Krutrim Centralized IAM Read Only Access Policy across all IAM resources</td><td><p>Users, </p><p>Groups, </p><p>Roles, </p><p>Policies, </p><p>Association Between Users/Groups/Roles/Policies</p></td></tr><tr><td>iam</td><td>KIAMReadWriteOnlyAccessAllResources</td><td>Krutrim Centralized IAM Read Write Access Policy across all IAM resources</td><td><p>Users, </p><p>Groups, </p><p>Roles, </p><p>Policies, </p><p>Association Between Users/Groups/Roles/Policies</p></td></tr><tr><td>iam</td><td>KIAMGroupManagerAccess</td><td>Krutrim Centralized IAM Group Management Access Policy</td><td>Groups</td></tr><tr><td>iam</td><td>KIAMGroupReadOnlyAccess</td><td>Krutrim Centralized IAM Group Read Only Access Policy</td><td>Groups</td></tr><tr><td>iam</td><td>KIAMGroupReadWriteAccess</td><td>Krutrim Centralized IAM Group read Write Access Policy</td><td>Groups</td></tr><tr><td>iam</td><td>KIAMMappingManagerAccess</td><td>Krutrim Centralized IAM User/Group/Role/Policies Association Full Access Policy</td><td>Association Between Users/Groups/Roles/Policies</td></tr><tr><td>iam</td><td>KIAMMappingReadOnlyAccess</td><td>Krutrim Centralized IAM User/Group/Role/Policies Association Read Only Access Policy</td><td>Groups</td></tr><tr><td>iam</td><td>KIAMMappingReadWriteAccess</td><td>Krutrim Centralized IAM User/Group/Role/Policies Association Read Write Access Policy</td><td>Groups</td></tr><tr><td>iam</td><td>KIAMPolicyManagerAccess</td><td>Krutrim Centralized IAM Policy Management Access Policy</td><td>Policies</td></tr><tr><td>iam</td><td>KIAMPolicyReadOnlyAccess</td><td>Krutrim Centralized IAM Policy Read Only Access Policy</td><td>Policies</td></tr><tr><td>iam</td><td>KIAMPolicyReadWriteAccess</td><td>Krutrim Centralized IAM Policy Read Write Access Policy</td><td>Policies</td></tr><tr><td>iam</td><td>KIAMRoleManagerAccess</td><td>Krutrim Centralized IAM Role Management Access Policy</td><td>Roles</td></tr><tr><td>iam</td><td>KIAMRoleReadOnlyAccess</td><td>Krutrim Centralized IAM Role Read Only Access Policy</td><td>Roles</td></tr><tr><td>iam</td><td>KIAMRolereadWriteAccess</td><td>Krutrim Centralized IAM Role Read write Access Policy</td><td>Roles</td></tr><tr><td>iam</td><td>KIAMUserManagerAccess</td><td>Krutrim Centralized IAM User Management Full Access Policy</td><td>Users</td></tr><tr><td>iam</td><td>KIAMUserReadOnlyAccess</td><td>Krutrim Centralized IAM User Read Only Access Policy</td><td>Users</td></tr><tr><td>iam</td><td>KIAMUserReadWriteAccess</td><td>Krutrim Centralized IAM User Read Write Access Policy</td><td>Users</td></tr><tr><td>inference</td><td>KInferenceFullAccess</td><td>Krutrim Inference Full Access Policy</td><td>Inference</td></tr><tr><td>inference</td><td>KInferenceReadOnlyAccess</td><td>Krutrim Inference Read Only Access Policy</td><td>Inference</td></tr><tr><td>inference</td><td>KInferenceReadWriteAccess</td><td>Krutrim Inference Read Write Access Policy</td><td>Inference</td></tr><tr><td>kbs</td><td>KBlockStorageFullAccess</td><td>Krutrim Block Storage Full Access Policy</td><td>Block Storage</td></tr><tr><td>kbs</td><td>KBlockStorageReadOnlyAccess</td><td>Krutrim Block Storage Read Only Access Policy</td><td>Block Storage</td></tr><tr><td>kbs</td><td>KBlockStorageReadWriteAccess</td><td>Krutrim Block Storage Read Write Access Policy</td><td>Block Storage</td></tr><tr><td>kcm</td><td>KCertManagerFullAccess</td><td>Krutrim Certificate Manager Full Access Policy</td><td>Certificates</td></tr><tr><td>kcm</td><td>KCertManagerReadOnlyAccess</td><td>Krutrim Certificate Manager Read Only Access Policy</td><td>Certificates</td></tr><tr><td>kcm</td><td>KCertManagerReadWriteAccess</td><td>Krutrim Certificate Manager Read Write Access Policy</td><td>Certificates</td></tr><tr><td>kks</td><td>KKSFullAccess</td><td>Kubernetes Full Access Policy</td><td>Kubernetes Cluster</td></tr><tr><td>kks</td><td>KKSReadAccess</td><td>Kubernetes Read Only Access Policy</td><td>Kubernetes Cluster</td></tr><tr><td>kks</td><td>KKSWriteAccess</td><td>Kubernetes Read and Write only Access Policy</td><td>Kubernetes Cluster</td></tr><tr><td>kos</td><td>KObjectStorageAccessKeyFullAccess</td><td>Krutrim Access Key Full Access Policy</td><td><p>KOS Access Keys,</p><p>KOS Buckets,</p><p>KOS Objects,</p><p>KOS Regions</p></td></tr><tr><td>kos</td><td>KObjectStorageFullAccess</td><td>Krutrim Object Storage Full Access Policy</td><td><p>KOS Access Keys,</p><p>KOS Buckets,</p><p>KOS Objects,</p><p>KOS Regions</p></td></tr><tr><td>kos</td><td>KObjectStorageReadOnlyAccess</td><td>Krutrim Object Storage Read Only Access Policy</td><td><p>KOS Access Keys,</p><p>KOS Buckets,</p><p>KOS Objects,</p><p>KOS Regions</p></td></tr><tr><td>kos</td><td>KObjectStorageReadWriteAccess</td><td>Krutrim Object Storage Read Write Access Policy</td><td><p>KOS Access Keys,</p><p>KOS Buckets,</p><p>KOS Objects,</p><p>KOS Regions</p></td></tr><tr><td>kpod</td><td>KKPodFullAccess</td><td>Krutrim KPod Full Access Policy</td><td>Kpods (AI Pods)</td></tr><tr><td>kpod</td><td>KKPodReadOnlyAccess</td><td>Krutrim KPod Read Only Access Policy</td><td>Kpods (AI Pods)</td></tr><tr><td>kpod</td><td>KKPodReadWriteAccess</td><td>Krutrim KPod Read Write Access Policy</td><td>Kpods (AI Pods)</td></tr><tr><td>loadbalancer</td><td>KLoadBalancerFullAccess</td><td>Krutrim Load Balancer Full Access Policy</td><td><p>Load Balancers,</p><p>Target Groups,</p><p>Listeners,</p><p>Health Monitors,</p><p>Rules,</p><p>Members</p></td></tr><tr><td>loadbalancer</td><td>KLoadBalancerReadOnlyAccess</td><td>Krutrim Load Balancer Read Only Access Policy</td><td><p>Load Balancers,</p><p>Target Groups,</p><p>Listeners,</p><p>Health Monitors,</p><p>Rules,</p><p>Members</p></td></tr><tr><td>loadbalancer</td><td>KLoadBalancerReadWriteAccess</td><td>Krutrim Load Balancer Read Write Access Policy</td><td><p>Load Balancers,</p><p>Target Groups,</p><p>Listeners,</p><p>Health Monitors,</p><p>Rules,</p><p>Members</p></td></tr><tr><td>maas</td><td>KMAASApiKeyManagerAccess</td><td>Krutrim MAAS API Key Full Access Policy</td><td>MaaS API Keys</td></tr><tr><td>maas</td><td>KMAASApiKeyReadOnlyAccess</td><td>Krutrim MAAS API Key Read Only Access Policy</td><td>MaaS API Keys</td></tr><tr><td>maas</td><td>KMAASApiKeyReadWriteAccess</td><td>Krutrim MAAS API Key Read Write Access Policy</td><td>MaaS API Keys</td></tr><tr><td>maas</td><td>KMAASFullAccess</td><td>Krutrim MAAS Full Access Policy</td><td><p>MaaS</p><p>MaaS API Keys</p></td></tr><tr><td>maas</td><td>KMAASReadOnlyAccess</td><td>Krutrim MAAS Read Only Access Policy</td><td><p>MaaS</p><p>MaaS API Keys</p></td></tr><tr><td>maas</td><td>KMAASReadWriteAccess</td><td>Krutrim MAAS Read Write Access Policy</td><td><p>MaaS</p><p>MaaS API Keys</p></td></tr><tr><td>modelRegistry</td><td>KModelRegistryFullAccess</td><td>Krutrim Model Registry Full Access Policy</td><td>Model Registry</td></tr><tr><td>modelRegistry</td><td>KModelRegistryReadOnlyAccess</td><td>Krutrim Model Registry Read Only Access Policy</td><td>Model Registry</td></tr><tr><td>modelRegistry</td><td>KModelRegistryReadWriteAccess</td><td>Krutrim Model Registry Read Write Access Policy</td><td>Model Registry</td></tr><tr><td>securityGroup</td><td>KSecurityGroupFullAccess</td><td>Security Group Full Access Policy</td><td>Security Groups</td></tr><tr><td>securityGroup</td><td>KSecurityGroupReadAccess</td><td>Security Group Read Only Access Policy</td><td>Security Groups</td></tr><tr><td>securityGroup</td><td>KSecurityGroupWriteAccess</td><td>Security Group Read and Write only Access Policy</td><td>Security Groups</td></tr><tr><td>sshkeys</td><td>KSSHFullAccess</td><td>Krutrim SSH Full Access Policy</td><td>SSH Keys</td></tr><tr><td>sshkeys</td><td>KSSHReadOnlyAccess</td><td>Krutrim SSH Read Only Access Policy</td><td>SSH Keys</td></tr><tr><td>sshkeys</td><td>KSSHReadWriteAccess</td><td>Krutrim SSH Read Write Access Policy</td><td>SSH Keys</td></tr><tr><td>vm</td><td>KVMFullAccess</td><td>Krutrim VM Full Access Policy</td><td>Virtual Machines</td></tr><tr><td>vm</td><td>KVMReadOnlyAccess</td><td>Krutrim VM Read Only Access Policy</td><td>Virtual Machines</td></tr><tr><td>vm</td><td>KVMReadWriteAccess</td><td>Krutrim VM Read Write Access Policy</td><td>Virtual Machines</td></tr><tr><td>vpc</td><td>KVPCFullAccess</td><td>Krutrim VPC Full Access Policy</td><td>VPC, Subnets, Security Groups, Static IPs</td></tr><tr><td>vpc</td><td>KVPCReadOnlyAccess</td><td>Krutrim VPC Read Only Access Policy</td><td>VPC, Subnets, Security Groups, Static IPs</td></tr><tr><td>vpc</td><td>KVPCReadWriteAccess</td><td>Krutrim VPC Read Write Access Policy</td><td>VPC, Subnets, Security Groups, Static IPs</td></tr></tbody></table>

</details>

{% hint style="success" %}
**The service names in the list above are the exact ones that can be used when accessing IAM programmatically**
{% endhint %}

***

#### Custom Policies

Custom (customer-managed) policies are defined and maintained by users that grant fine-grained, reusable permissions to identities while enforcing the principle of least privilege.

Characteristics:

* Created and maintained by the Root or IAM users (if permission given)
* Can be edited or deleted

### Policy JSON Examples&#x20;

#### Example 1: Full Access Default Policy

```
{
  "name": "KBlockStorageFullAccess",
  "description": "Krutrim Block Storage Full Access Policy",
  "statements": [
    {
      "service": "kbs",
      "resource": "*",
      "operation": "*",
      "effect": "allow"
    }
  ]
}
```

{% hint style="info" %}
The policy above allows:

* All CRUD operations on all KBS (Krutrim Block Storage) resources
  {% endhint %}

***

#### Example 2: Read Only Access Default Policy

```
{
  "name": "KASGReadOnlyAccess",
  "description": "Krutrim ASG Read Only Access Policy",
  "statements": [
    {
      "service": "asg",
      "resource": "*",
      "operation": "read",
      "effect": "allow"
    }
  ]
}
```

{% hint style="info" %}
The policy above allows:

* Allows only read operations on all ASG (Auto Scaling Group) resources
* No create, update, or delete permissions
  {% endhint %}

***

#### Example 3: Custom Policy (Explicit Deny)

```
{
  "name": "VPCFullAccessAllowAndKBSDeny",
  "description": "Allow full access to all VPC resource and deny KBS resource",
  "statements": [
    {
      "service": "vpc",
      "resource": "*",
      "operation": "*",
      "effect": "allow"
    },
    {
      "service": "kbs",
      "resource": "*",
      "operation": "*",
      "effect": "deny"
    }
  ]
}
```

{% hint style="info" %}
The policy above allows:

* Create, read, update and delete operations on all VPC resources
* Explicitly denies all access to Block Storage (KBS) resources
  {% endhint %}

***

#### Example 4: Custom Policy - Allow Kubernetes (KKS) Cluster Creation

```
{
  "Name": "FullKKSCluserAccess",
  "Description": "Allow to manage KKS clusters",
  "Statements": [
    {
      "Service": "kks",
      "Resource": "*",
      "Operation": "*",
      "Effect": "allow"
    },
    {
      "Service": "vpc",
      "Resource": "*",
      "Operation": "create,read,update",
      "Effect": "allow"
    }
  ]
}

```

{% hint style="info" %}
The policy above allows:

* Create, read, update and delete operations on all KKS resources
* Allows create, read, and update operations on all VPC resources<br>
  {% endhint %}

{% hint style="warning" %}
**To allow IAM users to create any resource, the root user needs to ensure that the IAM user is given all permissions to access / view the other services which are required to create the main resource, for example:**&#x20;

To allow an IAM user to create a Kubernetes (KKS) cluster, the necessary KKS permissions must be supplemented with permissions for other services. Specifically, during the KKS cluster creation process, the user needs the ability to view and select supporting resources, such as those related to VPC.
{% endhint %}

### Next Steps

* Attach policies to roles
* Assign roles to users or groups
* Use groups to scale access
* Review custom operations for fine-grained control


# Roles

### What Is a Role?

Roles define **what a user is allowed to do** in Krutrim Cloud. They are the primary mechanism used to grant permissions to users in a controlled and reusable way.

A role itself does not represent a person or a team. Instead, it represents a **set of permissions** that can be assigned to users directly or via groups.

A role is a logical grouping of one or more **policies**.

Roles:

* Bundle permissions into reusable units
* Enable least-privilege access design
* Allow consistent permission management across users and teams

A role has no effect unless it is assigned to at least one user or group.

***

### Permission Model

Roles sit between policies and users in the IAM permission model.

```
Policy → Role → (User | Group) → User
```

* Policies define **what actions are allowed or denied**
* Roles aggregate policies
* Users inherit permissions only through roles

Key characteristics:

* Roles do not inherit from other roles
* Roles cannot exist without policies
* Permissions are evaluated only through roles

***

### Managed Roles and Custom Roles

Krutrim Cloud supports two types of roles:

{% tabs %}
{% tab title="Managed (System-Managed) Roles" %}

#### Managed (System-Managed) Roles

Managed roles are predefined roles provided by Krutrim Cloud to cover common access patterns.

Managed roles:

* Are created and maintained by the system
* Cannot be edited
* Cannot be deleted
* Behave like regular roles during permission evaluation
  {% endtab %}

{% tab title="Custom Roles" %}

#### Custom Roles

Custom roles are created and managed by your organization.

Custom roles allow you to:

* Combine multiple policies
* Create fine-grained, least-privilege access
* Tailor permissions to specific job functions

Custom roles:

* Can be edited
* Can be deleted (after detaching)
* Are reusable across users and groups
  {% endtab %}
  {% endtabs %}

### Managed Roles and Permissions

The following managed roles are available by default:

| Role Name     | Description                               | Permissions Granted                               |
| ------------- | ----------------------------------------- | ------------------------------------------------- |
| Account Admin | Full administrative access to the account | All permissions except actions on the root user   |
| Viewer        | Read-only access across the account       | Read-only access to all resources except billing  |
| Billing       | Billing visibility                        | Read-only access to billing and usage information |

***

### Creating a Role

To create a custom role:

1. Navigate to **IAM → Roles**
2. Click **Create Role**
3. Provide:
   * **Role Name**&#x20;
   * **Description**&#x20;
4. Attach one or more policies
5. Click **Create Role**

Requirements:

* At least one policy must be attached
* Role name must be unique within the organization

***

#### Putting a Role Into Effect

Creating a role **does not automatically grant permissions** to any user.

To apply a role:

* **Assign the role to a user**
  1. Navigate to **IAM → Users**
  2. Open the user
  3. Click **Edit**
  4. Attach the role
  5. Save changes

**OR**

* **Assign the role to a group**
  1. Navigate to **IAM → Groups**
  2. Open the group
  3. Click **Edit**
  4. Attach the role
  5. Save changes

The role takes effect immediately for:

* The user (direct assignment), or
* All users who are members of the group

***

### Editing a Role

You can edit a role to:

* Update its name or description
* Add policies
* Remove policies

#### Downstream Impact of Editing

Editing a role has **immediate downstream effects**.

Any change to a role affects:

* All users directly assigned to the role
* All users who inherit the role via groups

Changes take effect immediately and may:

* Grant additional access
* Revoke existing access
* Break workflows for users

***

### Deleting a Role

Roles cannot be deleted while they are attached to users or groups.

To delete a role:

1. Identify all users and groups using the role
2. Navigate to each user or group
3. Remove the role
4. Return to the role
5. Delete the role

Deletion permanently removes the role and its permission bundle.

***

### Admin Callouts and Best Practices

#### Be Careful When Editing Roles

Editing roles can unintentionally impact multiple users at once.

Recommended practices:

* Communicate role changes in advance
* Review attached users and groups before editing
* Avoid frequent changes to widely-used roles

***

#### Prefer Creating New Roles Over Editing Existing Ones

If additional permissions are required:

**Recommended approach**

* Create a **new role** with the additional permissions
* Attach the new role to users or groups

**Avoid**

* Modifying existing roles that are already widely assigned

This approach:

* Prevents unexpected access changes
* Preserves auditability
* Allows safe rollback by detaching roles

***

#### Design Roles Around Job Functions

Good role design:

* Maps to job responsibilities (e.g. DevOps, Network Admin, Viewer)
* Remains stable over time
* Uses groups for large-scale assignment

Avoid:

* User-specific roles
* Overloaded “god roles”
* Frequent role churn

***

### Next Steps

* Attach roles to **Users** for direct access
* Use **Groups** to scale role assignment
* Review **Policies** to understand how permissions are defined

```
```


# Groups

Groups are used to **manage access for multiple users at once** by assigning roles collectively instead of individually.

A group does not define permissions on its own. It acts as a **container for roles**, and users inherit permissions by becoming members of a group.

***

### What Is a Group?

A group is a logical collection of **roles**.

Groups are designed to:

* Simplify access management for teams
* Reduce repetitive role assignments
* Minimize operational errors when onboarding or offboarding users

A group has no effect unless:

* At least one role is attached to it, and
* At least one user is added to the group

***

### What Groups Can and Cannot Do

#### Groups Can

* Contain one or more roles
* Be attached to users
* Grant all attached roles to all group members

#### Groups Cannot

* Contain policies directly
* Contain other groups (no nested groups)
* Be attached to other groups

### Creating a Group

To create a new group:

1. Navigate to **IAM → Groups**
2. Click **Create Group**
3. Enter:
   * **Group Name** (required)
   * **Description** (recommended)
4. Attach roles (optional at creation time)
   * Search is available to find roles
   * Both preset and custom roles can be attached
5. Click **Create Group**

***

### Putting a Group Into Effect

Creating a group alone does not grant access to anyone.

To apply a group:

* **Add users to the group**
  1. Navigate to **IAM → Users**
  2. Open a user
  3. Click **Edit**
  4. Attach the group
  5. Save changes

Once attached, the user immediately inherits:

* All roles attached to the group
* All permissions defined by those roles

***

### Editing a Group

You can edit a group to:

* Add roles
* Remove roles

#### Downstream Impact of Editing

{% hint style="warning" %}
Editing a group has immediate downstream effects.

Any change to a group affects:

* All users who are members of the group

Changes may:

* Grant additional access
* Revoke existing access
* Impact active workflows
  {% endhint %}

***

### Deleting a Group

Groups cannot be deleted while they are attached to users.

To delete a group:

1. Identify all users assigned to the group
2. Navigate to each user
3. Remove the group from the user
4. Return to the group
5. Delete the group

Deletion permanently removes the group and its role mappings.

***

### Best Practices

#### Use Groups for Teams

Groups are best suited for:

* Engineering teams
* Operations teams
* Functional roles (e.g., Networking, DevOps, Finance)

Avoid using groups for:

* Individual users
* Temporary or one-off access

***

#### Prefer Stable Group Definitions

Recommended:

* Keep group membership dynamic
* Keep role attachments stable

Avoid:

* Frequently changing roles attached to widely used groups
* Overloading a single group with too many roles

***

#### Combine Groups With Roles Carefully

Best practice pattern:

* Roles define **what access exists**
* Groups define **who gets that access**

This separation makes access easier to audit, safer to modify, and simpler to scale.

{% hint style="info" %}
We recommend creating a role and attaching it to a Group which is in turn attached to a user rather than directly attaching a role to a user along with groups. This helps with permission auditability as well.
{% endhint %}


# Pricing

Transparent pricing in INR. No hidden egress charges. No forex surprises.\
Krutrim Cloud helps Indian businesses scale confidently with predictable infrastructure costs built for Indian workloads and enterprise growth.

Whether you're exploring monthly usage, committed enterprise plans, or large-scale infrastructure deployments, our pricing is designed to stay simple, transparent, and cost-efficient at every stage of growth.

From startups launching their first workloads to enterprises running mission-critical platforms, Krutrim Cloud offers flexible pricing models tailored for performance, scale, and long-term operational efficiency.


# CPU and GPU

{% tabs %}
{% tab title="CPU" %}

#### 1. Compute - CPU

<table><thead><tr><th>Flavor</th><th>vCPU / RAM</th><th>Unit</th><th>On-Demand Price</th><th>Monthly Reserved</th><th>6 Month Reserved</th><th data-hidden>1 Year Reserved</th></tr></thead><tbody><tr><td>CPU-1x-4GB</td><td>1 vCPU / 4 GB</td><td>Hour</td><td>₹3.00</td><td>₹2.85</td><td>₹2.70</td><td>₹2.10</td></tr><tr><td>CPU-2x-8GB</td><td>2 vCPU / 8 GB</td><td>Hour</td><td>₹6.00</td><td>₹5.70</td><td>₹5.40</td><td>₹4.20</td></tr><tr><td>CPU-4x-16GB</td><td>4 vCPU / 16 GB</td><td>Hour</td><td>₹13.00</td><td>₹12.35</td><td>₹11.70</td><td>₹9.10</td></tr><tr><td>CPU-8x-32GB</td><td>8 vCPU / 32 GB</td><td>Hour</td><td>₹25.00</td><td>₹23.75</td><td>₹22.50</td><td>₹17.50</td></tr><tr><td>CPU-16x-64GB</td><td>16 vCPU / 64 GB</td><td>Hour</td><td>₹49.00</td><td>₹46.55</td><td>₹44.10</td><td>₹34.30</td></tr><tr><td>CPU-32x-128GB</td><td>32 vCPU / 128 GB</td><td>Hour</td><td>₹97.00</td><td>₹92.15</td><td>₹87.30</td><td>₹67.90</td></tr></tbody></table>
{% endtab %}

{% tab title="GPU" %}

<table><thead><tr><th>GPU Flavor</th><th>GPU Type / Count</th><th>RAM (GB)</th><th>GPU Memory (GB)</th><th>vCPUs</th><th>Unit</th><th>On-Demand Price</th><th>Monthly Reserved</th><th>6 Month Reserved</th><th data-hidden>1 Year Reserved</th></tr></thead><tbody><tr><td>A100-80GB-NVLINK-1x</td><td>A100 80GB ×1</td><td>96</td><td>80</td><td>24</td><td>Hour</td><td>₹189</td><td>₹148</td><td>₹132</td><td>₹98</td></tr><tr><td>H100-NVLINK-1x</td><td>H100 ×1</td><td>200</td><td>80</td><td>24</td><td>Hour</td><td>₹213</td><td>₹198</td><td>₹186</td><td>₹173</td></tr><tr><td>H100-NVLINK-2x</td><td>H100 ×2</td><td>400</td><td>160</td><td>48</td><td>Hour</td><td>₹426</td><td>₹396</td><td>₹372</td><td>₹346</td></tr><tr><td>H100-NVLINK-4x</td><td>H100 ×4</td><td>800</td><td>320</td><td>96</td><td>Hour</td><td>₹852</td><td>₹792</td><td>₹744</td><td>₹692</td></tr></tbody></table>
{% endtab %}

{% tab title="AI Pods" %}

| Flavor                  | GPU Config  | RAM (GB) | GPU Memory (GB) | vCPUs | Unit | On-Demand Price |
| ----------------------- | ----------- | -------- | --------------- | ----- | ---- | --------------- |
| A100-NVLINK-Tiny        | A100 (Tiny) | 30       | 5               | 16    | Hour | ₹24.00          |
| A100-NVLINK-Nano        | A100 (Nano) | 60       | 10              | 16    | Hour | ₹49.00          |
| A100-NVLINK-Mini        | A100 (Mini) | 60       | 20              | 16    | Hour | ₹73.00          |
| A100-NVLINK-Standard-1x | A100 ×1     | 60       | 40              | 16    | Hour | ₹170.00         |
| A100-NVLINK-Standard-2x | A100 ×2     | 125      | 80              | 16    | Hour | ₹340.00         |
| A100-NVLINK-Standard-4x | A100 ×4     | 250      | 160             | 128   | Hour | ₹510.00         |
| A100-NVLINK-Standard-8x | A100 ×8     | 1000     | 320             | 128   | Hour | ₹1,360.00       |
| H100-NVLINK-Tiny        | H100 (Tiny) | 60       | 10              | 16    | Hour | ₹30.00          |
| H100-NVLINK-Nano        | H100 (Nano) | 60       | 20              | 16    | Hour | ₹61.00          |
| H100-NVLINK-Mini        | H100 (Mini) | 60       | 40              | 16    | Hour | ₹91.00          |
| H100-NVLINK-Standard-1x | H100 ×1     | 125      | 80              | 16    | Hour | ₹213.00         |
| H100-NVLINK-Standard-2x | H100 ×2     | 250      | 160             | 52    | Hour | ₹425.00         |
| H100-NVLINK-Standard-4x | H100 ×4     | 1004     | 320             | 104   | Hour | ₹850.00         |
| H100-NVLINK-Standard-8x | H100 ×8     | 2008     | 640             | 208   | Hour | ₹1,700.00       |

AI Pods Storage

| Storage Type   | Flavor         | Unit | Price / GB / Hour | Price / GB / Month |
| -------------- | -------------- | ---- | ----------------- | ------------------ |
| Ephemeral-SSD  | Ephemeral-SSD  | Hour | ₹0.006            | ₹4.38              |
| Persistent-SSD | Persistent-SSD | Hour | ₹0.006            | ₹4.38              |
| {% endtab %}   |                |      |                   |                    |
| {% endtabs %}  |                |      |                   |                    |


# Storage

Block Storage

| Storage Type  | Flavor       | Unit | Price / GB / Hour | Price / GB / Month |
| ------------- | ------------ | ---- | ----------------- | ------------------ |
| Block Storage | Volume-SSD   | Hour | ₹0.011            | ₹7.88              |
| Snapshot      | Snapshot-SSD | Hour | ₹0.006            | ₹4.38              |
| Backup        | Backup-SSD   | Hour | ₹0.003            | ₹1.83              |

Object Storage

| Storage Type / Tier | Flavor         | Unit | Price / GB / Hour | Price / GB / Month |
| ------------------- | -------------- | ---- | ----------------- | ------------------ |
| Tier 1              | 0 – 5 GB       | Hour | ₹0                | ₹0                 |
| Tier 2              | 5 GB – 50 TB   | Hour | ₹0.0023           | ₹1.66              |
| Tier 3              | 50 TB – 500 TB | Hour | ₹0.0022           | ₹1.61              |
| Tier 4              | Above 500 TB   | Hour | ₹0.0021           | ₹1.54              |


# Networking

| Service                    | Flavor                                        | Unit                | Price / Hour | Price / Month |
| -------------------------- | --------------------------------------------- | ------------------- | ------------ | ------------- |
| VPC                        | *Charges apply  once resources are attached.* | Hour                | ₹0.28        | ₹204          |
| IP Addresses               | Floating IP                                   | Hour                | ₹0.28        | ₹204          |
| DNS Base Charge - Per Zone | Up to 25                                      | Hour                | ₹0.031       | ₹22.04        |
| DNS Base Charge - Per Zone | Above 25                                      | Hour                | ₹0.012       | ₹8.81         |
| DNS Zones - Query Charges  | Up to 1 Billion                               | Per million queries | —            | ₹35.26        |
| DNS Zones - Query Charges  | Above 1 Billion                               | Per million queries | —            | ₹17.63        |


# Load Balancers

| Service                   | Flavor               | Unit | Price / Hour | Price / Month |
| ------------------------- | -------------------- | ---- | ------------ | ------------- |
| Application Load Balancer | Base Charge          | Hour | ₹8.00        | ₹5,840        |
| Application Load Balancer | Data Transfer Charge | GB   | —            | ₹0.40         |
| Network Load Balancer     | Base Charge          | Hour | ₹8.00        | ₹5,840        |
| Network Load Balancer     | Data Transfer Charge | GB   | —            | ₹0.20         |


# Kubernetes

| Service    | Flavor        | Unit | Price / Hour | Price / Month |
| ---------- | ------------- | ---- | ------------ | ------------- |
| Kubernetes | Control Plane | Hour | ₹7.00        | ₹5,110        |


# Object Storage API

## GET /kos/v1/buckets

> Get all buckets

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketsResponse":{"properties":{"totalItems":{"description":"Total number of items","type":"integer"},"totalPages":{"description":"Total number of pages","type":"integer"},"currentPage":{"description":"Current page number","type":"integer"},"nextPage":{"description":"Next page number, if available","type":"integer"},"items":{"items":{"$ref":"#/components/schemas/BucketResponse"},"type":"array"}},"type":"object"},"BucketResponse":{"properties":{"name":{"nullable":true,"type":"string"},"krnid":{"nullable":true,"type":"string"},"owner":{"type":"string"},"account_id":{"type":"string"},"createdAt":{"format":"date-time","nullable":true,"type":"string"},"usedCapacity":{"format":"double","nullable":true,"type":"number"},"allocatedCapacity":{"format":"int64","nullable":true,"type":"integer"},"region":{"nullable":true,"type":"string"},"url":{"nullable":true,"type":"string"},"status":{"nullable":true,"type":"string"},"path":{"nullable":true,"type":"string"},"protocol":{"nullable":true,"type":"string"},"tags":{"additionalProperties":true,"nullable":true,"type":"object"},"versioning":{"nullable":true,"type":"boolean"},"anonymous_access":{"nullable":true,"type":"boolean"},"tier":{"nullable":true,"type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets":{"get":{"parameters":[{"description":"Page number of the results to fetch","explode":true,"in":"query","name":"page","required":false,"schema":{"type":"integer"},"style":"form"},{"description":"Number of results per page","explode":true,"in":"query","name":"page_size","required":false,"schema":{"type":"integer"},"style":"form"},{"description":"search query","explode":true,"in":"query","name":"name_filter","required":false,"schema":{"type":"string"},"style":"form"},{"description":"refresh","explode":true,"in":"query","name":"refresh","required":false,"schema":{"default":false,"type":"boolean"},"style":"form"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketsResponse"}}},"description":"Bucket successfully retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Get all buckets","tags":["Buckets"]}}}}
```

## POST /kos/v1/buckets

> Creates a new bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketCreationPayload":{"properties":{"name":{"type":"string"},"description":{"type":"string"},"tags":{"additionalProperties":true,"type":"object"},"versioning":{"type":"boolean"},"anonymous_access":{"type":"boolean"}},"type":"object"},"BucketCreationResponse":{"properties":{"krn":{"type":"string"},"bucketName":{"type":"string"},"createdAt":{"format":"date-time","type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorConflict":{"description":"Conflict with existing resource","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnprocessableEntity":{"description":"Unprocessable entity","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets":{"post":{"operationId":"createBucket","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketCreationPayload"}}},"description":"Bucket creation payload","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketCreationResponse"}}},"description":"Bucket successfully created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorConflict"}}},"description":"Conflict, bucket already exists"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnprocessableEntity"}}},"description":"Unprocessable entity, validation error"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Creates a new bucket","tags":["Buckets"]}}}}
```

## GET /kos/v1/buckets/{bucketId}

> Retrieves bucket information

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketResponse":{"properties":{"name":{"nullable":true,"type":"string"},"krnid":{"nullable":true,"type":"string"},"owner":{"type":"string"},"account_id":{"type":"string"},"createdAt":{"format":"date-time","nullable":true,"type":"string"},"usedCapacity":{"format":"double","nullable":true,"type":"number"},"allocatedCapacity":{"format":"int64","nullable":true,"type":"integer"},"region":{"nullable":true,"type":"string"},"url":{"nullable":true,"type":"string"},"status":{"nullable":true,"type":"string"},"path":{"nullable":true,"type":"string"},"protocol":{"nullable":true,"type":"string"},"tags":{"additionalProperties":true,"nullable":true,"type":"object"},"versioning":{"nullable":true,"type":"boolean"},"anonymous_access":{"nullable":true,"type":"boolean"},"tier":{"nullable":true,"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}":{"get":{"operationId":"getBucket","parameters":[{"description":"ID of the bucket to retrieve","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketResponse"}}},"description":"Bucket information retrieved successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Retrieves bucket information","tags":["Buckets"]}}}}
```

## PUT /kos/v1/buckets/{bucketId}

> Updates bucket tags

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketUpdatePayload":{"properties":{"tags":{"additionalProperties":true,"type":"object"},"versioning":{"type":"boolean"},"anonymous_access":{"type":"boolean"}},"type":"object"},"BucketResponse":{"properties":{"name":{"nullable":true,"type":"string"},"krnid":{"nullable":true,"type":"string"},"owner":{"type":"string"},"account_id":{"type":"string"},"createdAt":{"format":"date-time","nullable":true,"type":"string"},"usedCapacity":{"format":"double","nullable":true,"type":"number"},"allocatedCapacity":{"format":"int64","nullable":true,"type":"integer"},"region":{"nullable":true,"type":"string"},"url":{"nullable":true,"type":"string"},"status":{"nullable":true,"type":"string"},"path":{"nullable":true,"type":"string"},"protocol":{"nullable":true,"type":"string"},"tags":{"additionalProperties":true,"nullable":true,"type":"object"},"versioning":{"nullable":true,"type":"boolean"},"anonymous_access":{"nullable":true,"type":"boolean"},"tier":{"nullable":true,"type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}":{"put":{"operationId":"updateBucket","parameters":[{"description":"ID of the bucket to update","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketUpdatePayload"}}},"description":"Bucket update payload","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketResponse"}}},"description":"Bucket tags successfully updated"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Updates bucket tags","tags":["Buckets"]}}}}
```

## DELETE /kos/v1/buckets/{bucketId}

> Deletes a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketDeletionPayload":{"properties":{"otp":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}":{"delete":{"operationId":"deleteBucket","parameters":[{"description":"ID of the bucket to delete","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketDeletionPayload"}}}},"responses":{"204":{"description":"Bucket successfully deleted, no content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Deletes a bucket","tags":["Buckets"]}}}}
```

## DELETE /internal/kos/v1/access\_keys\_all

> Deletes all access keys

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"Error":{"properties":{"message":{"description":"The failure message for the error.","type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/access_keys_all":{"delete":{"operationId":"deleteAllAccessKeys","responses":{"204":{"description":"Access keys successfully deleted, no content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Access keys not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Deletes all access keys","tags":["Buckets"]}}}}
```

## GET /kos/v1/access\_keys

> Retrieves a list of access keys

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"getAccessKeys_200_response_inner":{"properties":{"access_key":{"type":"string"},"created_date":{"format":"date-time","type":"string"},"region":{"type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/access_keys":{"get":{"operationId":"getAccessKeys","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/getAccessKeys_200_response_inner"},"type":"array"}}},"description":"Access keys successfully retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Access key not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Retrieves a list of access keys","tags":["Buckets"]}}}}
```

## POST /kos/v1/access\_keys

> Creates access keys

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"AccessKeysResponse":{"properties":{"access_key":{"type":"string"},"secret_key":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/access_keys":{"post":{"operationId":"createAccessKeys","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessKeysResponse"}}},"description":"Access keys successfully created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Creates access keys","tags":["Buckets"]}}}}
```

## DELETE /kos/v1/access\_keys/{accessKey}

> Deletes an access key

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[{"description":"Operations related to buckets","name":"Buckets"}],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"DeleteAccessKeyPayload":{"properties":{"otp":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/access_keys/{accessKey}":{"delete":{"operationId":"deleteAccessKey","parameters":[{"description":"ID of the access key to delete","explode":false,"in":"path","name":"accessKey","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccessKeyPayload"}}},"required":true},"responses":{"204":{"description":"Access key successfully deleted, no content"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Access key not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Deletes an access key","tags":["Buckets"]}}}}
```

## GET /kos/v1/buckets/{bucketId}/lifecycle-rules

> Get all lifecycle rules for a specific bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"LifecycleRulesResponse":{"items":{"$ref":"#/components/schemas/LifecycleRuleResponse"},"type":"array"},"LifecycleRuleResponse":{"allOf":[{"$ref":"#/components/schemas/LifecycleRulePayload"},{"properties":{"id":{"description":"Unique ID of the lifecycle rule","type":"string"},"status":{"description":"Status of the lifecycle rule","type":"string"}},"type":"object"}]},"LifecycleRulePayload":{"properties":{"name":{"description":"Name of the lifecycle rule","type":"string"},"enabled":{"nullable":true,"type":"boolean"},"expiration_days":{"nullable":true,"type":"integer"},"expired_obj_delete_marker":{"nullable":true,"type":"boolean"},"noncurrent_days":{"nullable":true,"type":"integer"},"newer_noncurrent_versions":{"nullable":true,"type":"integer"},"delete_incomplete_mpu":{"nullable":true,"type":"integer"},"attribute":{"description":"Attribute used to calculate object age","nullable":true,"type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/lifecycle-rules":{"get":{"operationId":"getAllLifecycleRules","parameters":[{"description":"ID of the bucket to retrieve lifecycle rules for","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRulesResponse"}}},"description":"Lifecycle rules successfully retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service unavailable"}},"summary":"Get all lifecycle rules for a specific bucket","tags":["LifecycleRules"]}}}}
```

## POST /kos/v1/buckets/{bucketId}/lifecycle-rules

> Create a new lifecycle rule for a specific bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"LifecycleRulePayload":{"properties":{"name":{"description":"Name of the lifecycle rule","type":"string"},"enabled":{"nullable":true,"type":"boolean"},"expiration_days":{"nullable":true,"type":"integer"},"expired_obj_delete_marker":{"nullable":true,"type":"boolean"},"noncurrent_days":{"nullable":true,"type":"integer"},"newer_noncurrent_versions":{"nullable":true,"type":"integer"},"delete_incomplete_mpu":{"nullable":true,"type":"integer"},"attribute":{"description":"Attribute used to calculate object age","nullable":true,"type":"string"}},"type":"object"},"LifecycleRuleResponse":{"allOf":[{"$ref":"#/components/schemas/LifecycleRulePayload"},{"properties":{"id":{"description":"Unique ID of the lifecycle rule","type":"string"},"status":{"description":"Status of the lifecycle rule","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/lifecycle-rules":{"post":{"operationId":"createLifecycleRule","parameters":[{"description":"ID of the bucket to which the lifecycle rule will be added","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRulePayload"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRuleResponse"}}},"description":"Lifecycle rule successfully created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict with existing resource"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service unavailable"}},"summary":"Create a new lifecycle rule for a specific bucket","tags":["LifecycleRules"]}}}}
```

## GET /kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}

> Get a specific lifecycle rule for a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"LifecycleRuleResponse":{"allOf":[{"$ref":"#/components/schemas/LifecycleRulePayload"},{"properties":{"id":{"description":"Unique ID of the lifecycle rule","type":"string"},"status":{"description":"Status of the lifecycle rule","type":"string"}},"type":"object"}]},"LifecycleRulePayload":{"properties":{"name":{"description":"Name of the lifecycle rule","type":"string"},"enabled":{"nullable":true,"type":"boolean"},"expiration_days":{"nullable":true,"type":"integer"},"expired_obj_delete_marker":{"nullable":true,"type":"boolean"},"noncurrent_days":{"nullable":true,"type":"integer"},"newer_noncurrent_versions":{"nullable":true,"type":"integer"},"delete_incomplete_mpu":{"nullable":true,"type":"integer"},"attribute":{"description":"Attribute used to calculate object age","nullable":true,"type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}":{"get":{"operationId":"getLifecycleRule","parameters":[{"description":"ID of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"},{"description":"ID of the lifecycle rule to retrieve","explode":false,"in":"path","name":"ruleId","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRuleResponse"}}},"description":"Lifecycle rule retrieved successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service unavailable"}},"summary":"Get a specific lifecycle rule for a bucket","tags":["LifecycleRules"]}}}}
```

## PUT /kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}

> Update a lifecycle rule for a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"LifecycleRulePayload":{"properties":{"name":{"description":"Name of the lifecycle rule","type":"string"},"enabled":{"nullable":true,"type":"boolean"},"expiration_days":{"nullable":true,"type":"integer"},"expired_obj_delete_marker":{"nullable":true,"type":"boolean"},"noncurrent_days":{"nullable":true,"type":"integer"},"newer_noncurrent_versions":{"nullable":true,"type":"integer"},"delete_incomplete_mpu":{"nullable":true,"type":"integer"},"attribute":{"description":"Attribute used to calculate object age","nullable":true,"type":"string"}},"type":"object"},"LifecycleRuleResponse":{"allOf":[{"$ref":"#/components/schemas/LifecycleRulePayload"},{"properties":{"id":{"description":"Unique ID of the lifecycle rule","type":"string"},"status":{"description":"Status of the lifecycle rule","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}":{"put":{"operationId":"updateLifecycleRule","parameters":[{"description":"ID of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"},{"description":"ID of the lifecycle rule to update","explode":false,"in":"path","name":"ruleId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRulePayload"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifecycleRuleResponse"}}},"description":"Lifecycle rule successfully updated"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service unavailable"}},"summary":"Update a lifecycle rule for a bucket","tags":["LifecycleRules"]}}}}
```

## DELETE /kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}

> Delete a lifecycle rule for a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/lifecycle-rules/{ruleId}":{"delete":{"operationId":"deleteLifecycleRule","parameters":[{"description":"ID of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"},{"description":"ID of the lifecycle rule to delete","explode":false,"in":"path","name":"ruleId","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"204":{"description":"Lifecycle rule successfully deleted"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Resource not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service unavailable"}},"summary":"Delete a lifecycle rule for a bucket","tags":["LifecycleRules"]}}}}
```

## GET /internal/kos/v1/policy

> Retrieves a policy

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy":{"get":{"operationId":"getPolicy","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Retrieves a policy","tags":["Policies"]}}}}
```

## POST /internal/kos/v1/policy

> Creates a policy

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyPayload":{"properties":{"_id":{"description":"Unique ID of the policy","type":"string"},"name":{"description":"Name of the policy","type":"string"},"statements":{"description":"Statements of the policy","items":{"type":"object"},"type":"array"},"conditions":{"description":"Conditions of the policy","items":{"type":"object"},"type":"array"},"accountId":{"description":"Account ID of the policy","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"}},"type":"object"},"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy":{"post":{"operationId":"createPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyPayload"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully created"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Invalid request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy already exists"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable entity, validation error"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Creates a policy","tags":["Policies"]}}}}
```

## POST /internal/kos/v1/policy/attach

> Attaches a policy to a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyAttachPayload":{"properties":{"policyKRNs":{"description":"Unique IDs of the policies","items":{"type":"string"},"type":"array"},"users":{"description":"KCIDs of the users","items":{"$ref":"#/components/schemas/UserDetails"},"type":"array"}},"type":"object"},"UserDetails":{"properties":{"kcid":{"description":"KCID of the user","type":"string"},"krn":{"description":"KRN of the user","type":"string"},"accountId":{"description":"Account ID of the user","type":"string"}},"type":"object"},"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy/attach":{"post":{"operationId":"attachPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyAttachPayload"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully attached"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Invalid request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Attaches a policy to a bucket","tags":["Policies"]}}}}
```

## POST /internal/kos/v1/policy/detach

> Detaches a policy from a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyDetachPayload":{"properties":{"users":{"description":"KCIDs of the users","items":{"$ref":"#/components/schemas/UserDetails"},"type":"array"},"policyKRNs":{"description":"Unique IDs of the policies","items":{"type":"string"},"type":"array"}},"type":"object"},"UserDetails":{"properties":{"kcid":{"description":"KCID of the user","type":"string"},"krn":{"description":"KRN of the user","type":"string"},"accountId":{"description":"Account ID of the user","type":"string"}},"type":"object"},"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy/detach":{"post":{"operationId":"detachPolicy","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyDetachPayload"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully detached"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Invalid request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Detaches a policy from a bucket","tags":["Policies"]}}}}
```

## GET /internal/kos/v1/policy/{policykrn}

> Retrieves a policy

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy/{policykrn}":{"get":{"operationId":"getPolicybyId","parameters":[{"description":"ID of the policy","explode":false,"in":"path","name":"policykrn","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully retrieved"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Retrieves a policy","tags":["Policies"]}}}}
```

## PUT /internal/kos/v1/policy/{policykrn}

> Updates a policy

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"PolicyPayload":{"properties":{"_id":{"description":"Unique ID of the policy","type":"string"},"name":{"description":"Name of the policy","type":"string"},"statements":{"description":"Statements of the policy","items":{"type":"object"},"type":"array"},"conditions":{"description":"Conditions of the policy","items":{"type":"object"},"type":"array"},"accountId":{"description":"Account ID of the policy","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"}},"type":"object"},"PolicyResponse":{"allOf":[{"properties":{"name":{"description":"policy Name","type":"string"},"policyKRN":{"description":"Unique ID of the policy","type":"string"},"CreationDate":{"description":"Creation date of the policy","type":"string"}},"type":"object"}]},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy/{policykrn}":{"put":{"operationId":"updatePolicy","parameters":[{"description":"ID of the policy","explode":false,"in":"path","name":"policykrn","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyPayload"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}},"description":"Policy successfully updated"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Updates a policy","tags":["Policies"]}}}}
```

## DELETE /internal/kos/v1/policy/{policykrn}

> Deletes a policy

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/internal/kos/v1/policy/{policykrn}":{"delete":{"operationId":"deletePolicy","parameters":[{"description":"ID of the policy","explode":false,"in":"path","name":"policykrn","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"204":{"description":"Policy successfully deleted"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Deletes a policy","tags":["Policies"]}}}}
```

## Activate a new session for API access

> Creates a new session for accessing protected APIs. \
> \- If a previous session exists and is still active, it will be invalidated\
> \- Sessions automatically expire after the configured timeout\
> \- Only one active session is allowed per set of credentials<br>

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"activateSession_request":{"properties":{"accessKey":{"description":"Access key for authentication","type":"string"},"secretKey":{"description":"Secret key for authentication","type":"string"}},"required":["accessKey","secretKey"],"type":"object"},"activateSession_200_response":{"properties":{"sessionToken":{"description":"Session token to be used for protected APIs","type":"string"},"expiresAt":{"description":"Session expiration timestamp","format":"date-time","type":"string"},"refreshToken":{"description":"Token used to refresh the session before expiration","type":"string"},"lastActiveAt":{"description":"Timestamp of last activity","format":"date-time","type":"string"}},"type":"object"},"activateSession_400_response":{"properties":{"error":{"description":"Error message","type":"string"},"code":{"enum":["INVALID_CREDENTIALS","MALFORMED_REQUEST"],"type":"string"}},"type":"object"},"activateSession_429_response":{"properties":{"error":{"type":"string"},"retryAfter":{"description":"Seconds to wait before retrying","type":"integer"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/sessions/activate":{"post":{"description":"Creates a new session for accessing protected APIs. \n- If a previous session exists and is still active, it will be invalidated\n- Sessions automatically expire after the configured timeout\n- Only one active session is allowed per set of credentials\n","operationId":"activateSession","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/activateSession_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/activateSession_200_response"}}},"description":"Session activated successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/activateSession_400_response"}}},"description":"Invalid credentials or request format"},"401":{"description":"Unauthorized - Invalid credentials"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/activateSession_429_response"}}},"description":"Too many session activation attempts"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Activate a new session for API access","tags":["Session Management"]}}}}
```

## Deactivate current session

> Explicitly deactivates the current session.\
> \- Invalidates the session token\
> \- Blocks access to protected APIs\
> \- Cleans up session resources<br>

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{},"schemas":{"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/sessions/deactivate/{sessionToken}":{"delete":{"description":"Explicitly deactivates the current session.\n- Invalidates the session token\n- Blocks access to protected APIs\n- Cleans up session resources\n","operationId":"deactivateSession","parameters":[{"explode":false,"in":"path","name":"sessionToken","required":true,"schema":{"description":"Session token","type":"string"},"style":"simple"}],"responses":{"204":{"description":"Session deactivated successfully"},"401":{"description":"Invalid session token"},"404":{"description":"Session not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Deactivate current session","tags":["Session Management"]}}}}
```

## Refresh current session

> Extends the current session lifetime before it expires

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{},"schemas":{"refreshSession_request":{"properties":{"refreshToken":{"type":"string"}},"required":["refreshToken"],"type":"object"},"refreshSession_200_response":{"properties":{"sessionToken":{"type":"string"},"expiresAt":{"format":"date-time","type":"string"},"refreshToken":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/sessions/refresh/{sessionToken}":{"post":{"description":"Extends the current session lifetime before it expires","operationId":"refreshSession","parameters":[{"explode":false,"in":"path","name":"sessionToken","required":true,"schema":{"description":"Session token","type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/refreshSession_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/refreshSession_200_response"}}},"description":"Session refreshed successfully"},"401":{"description":"Invalid refresh token or session"},"404":{"description":"Session not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Refresh current session","tags":["Session Management"]}}}}
```

## Get current session status

> Returns the status and details of the current session

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{},"schemas":{"getSessionStatus_200_response":{"properties":{"isActive":{"type":"boolean"},"expiresAt":{"format":"date-time","type":"string"},"lastActiveAt":{"format":"date-time","type":"string"},"createdAt":{"format":"date-time","type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/sessions/status/{sessionToken}":{"get":{"description":"Returns the status and details of the current session","operationId":"getSessionStatus","parameters":[{"explode":false,"in":"path","name":"sessionToken","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/getSessionStatus_200_response"}}},"description":"Session status retrieved successfully"},"401":{"description":"Invalid or expired session token"},"404":{"description":"Session not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Get current session status","tags":["Session Management"]}}}}
```

## POST /kos/v1/buckets/{bucketId}/objects/delete

> Delete an object

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"deleteObject_request":{"properties":{"objectkey":{"description":"The key of the object to delete","type":"string"}},"type":"object"},"deleteObject_200_response":{"properties":{"message":{"type":"string"},"objectKey":{"description":"The key of the deleted file","type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects/delete":{"post":{"operationId":"deleteObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/deleteObject_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/deleteObject_200_response"}}},"description":"File deleted successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized, invalid credentials"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Object not found or bucket does not exist"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Delete an object","tags":["ObjectsOperations"]}}}}
```

## GET /kos/v1/buckets/{bucketId}/objects

> List objects in a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"listObjects_200_response":{"properties":{"prefix":{"description":"The folder path prefix for objects","type":"string"},"objects":{"items":{"$ref":"#/components/schemas/listObjects_200_response_objects_inner"},"type":"array"}},"type":"object"},"listObjects_200_response_objects_inner":{"properties":{"key":{"description":"The object's key (path within bucket)","type":"string"},"size":{"description":"Object size in bytes","type":"integer"},"lastModified":{"description":"Last modified date","format":"date-time","type":"string"},"isFolder":{"description":"True if the object is a folder (common prefix)","type":"boolean"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects":{"get":{"operationId":"listObjects","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"},{"description":"Filter objects by prefix (like a folder path)","explode":true,"in":"query","name":"prefix","required":false,"schema":{"type":"string"},"style":"form"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/listObjects_200_response"}}},"description":"List of objects in the bucket"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized, invalid credentials"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"List objects in a bucket","tags":["ObjectsOperations"]}}}}
```

## PUT /kos/v1/buckets/{bucketId}/objects

> Upload a new object

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"uploadObject_request":{"properties":{"prefix":{"description":"The folder path prefix for objects","type":"string"}},"type":"object"},"uploadObject_201_response":{"properties":{"message":{"type":"string"},"objectKey":{"description":"The key of the uploaded file","type":"string"}},"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects":{"put":{"operationId":"uploadObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/uploadObject_request"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/uploadObject_201_response"}}},"description":"File uploaded successfully"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized, invalid credentials"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Upload a new object","tags":["ObjectsOperations"]}}}}
```

## POST /kos/v1/buckets/{bucketId}/objects/download

> Download an object

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"downloadObject_request":{"properties":{"objectkey":{"description":"The key of the object to download","type":"string"}},"type":"object"},"downloadObject_200_response":{"properties":{"message":{"type":"string"},"objectKey":{"description":"The key and preSignedUrl of the download file","type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects/download":{"post":{"operationId":"downloadObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/downloadObject_request"}}},"required":true},"responses":{"200":{"content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/downloadObject_200_response"}}},"description":"The file content as binary"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized, invalid credentials"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Object not found or bucket does not exist"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Download an object","tags":["ObjectsOperations"]}}}}
```

## POST /kos/v1/buckets/{bucketId}/objects/metadata

> Get object metadata

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"getObject_request":{"properties":{"objectkey":{"description":"The key of the object to download","type":"string"}},"type":"object"},"getObject_200_response":{"properties":{"key":{"description":"Object key (path within bucket)","type":"string"},"size_bytes":{"description":"Object size in bytes","format":"int64","type":"integer"},"storage_class":{"description":"Storage class of the object","type":"string"},"lastModified":{"description":"Last modified date","type":"string"},"contentType":{"description":"MIME type of the object","type":"string"},"etag":{"description":"ETag of the object","type":"string"}},"required":["key","lastModified","size_bytes"],"type":"object"},"ErrorResponse":{"properties":{"code":{"type":"integer"},"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects/metadata":{"post":{"operationId":"getObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/getObject_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/getObject_200_response"}}},"description":"Metadata of the object"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized, invalid credentials"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Object not found or bucket does not exist"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"}},"summary":"Get object metadata","tags":["ObjectsOperations"]}}}}
```

## POST /kos/v1/buckets/{bucketId}/objects/move

> Move or copy an object within a bucket

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"moveObject_request":{"properties":{"sourceKey":{"description":"Source object key","type":"string"},"destinationKey":{"description":"Destination object key","type":"string"},"action":{"description":"Action to perform (move or copy)","enum":["move","copy"],"type":"string"}},"type":"object"},"moveObject_200_response":{"properties":{"message":{"type":"string"},"sourceKey":{"description":"Source key","type":"string"},"destinationKey":{"description":"Destination key","type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects/move":{"post":{"operationId":"moveObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/moveObject_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/moveObject_200_response"}}},"description":"File moved or copied successfully"}},"summary":"Move or copy an object within a bucket","tags":["ObjectsOperations"]}}}}
```

## Rename an object within the bucket

> Rename an object by copying it to a new key and deleting the original.

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"renameObject_request":{"properties":{"oldKey":{"description":"The old key for the object (the old name/path for the file)","type":"string"},"newKey":{"description":"The new key for the object (the new name/path for the file)","type":"string"}},"type":"object"},"renameObject_200_response":{"properties":{"message":{"type":"string"},"oldKey":{"description":"Original key of the object","type":"string"},"newKey":{"description":"New key of the object","type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/{bucketId}/objects/rename":{"post":{"description":"Rename an object by copying it to a new key and deleting the original.","operationId":"renameObject","parameters":[{"description":"Krn identifier of the bucket","explode":false,"in":"path","name":"bucketId","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/renameObject_request"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/renameObject_200_response"}}},"description":"Object renamed successfully"},"400":{"description":"Invalid request parameters"},"404":{"description":"Object not found"}},"summary":"Rename an object within the bucket","tags":["ObjectsOperations"]}}}}
```

## Get Bucket Policy Details

> Returns details of a specified bucket policy.

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketPolicy":{"properties":{"bucketPolicyKrn":{"description":"Unique Key Resource Name (KRN) of the bucket policy.","type":"string"},"bucketKrn":{"description":"Unique Key Resource Name (KRN) of the bucket policy.","type":"string"},"s3_read_write_ips":{"description":"S3 hosts with read/write permissions.","items":{"type":"string"},"type":"array"},"s3_read_only_ips":{"description":"S3 hosts with read-only permissions.","items":{"type":"string"},"type":"array"},"created_at":{"description":"Creation timestamp of the policy.","format":"date-time","type":"string"},"updated_at":{"description":"Last updated timestamp of the policy.","format":"date-time","type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/policy/{bucketKrn}":{"get":{"description":"Returns details of a specified bucket policy.","parameters":[{"description":"The unique bucketKrn (Key Resource Name) of the bucket policy.","explode":false,"in":"path","name":"bucketKrn","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketPolicy"}}},"description":"Details of the bucket policy."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Get Bucket Policy Details","tags":["BucketPolicies"]}}}}
```

## Create a Bucket Policy

> Creates a new bucket policy.

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketPolicyCreate":{"properties":{"s3_read_write_ips":{"description":"S3 hosts with read/write permissions.","items":{"type":"string"},"type":"array"},"s3_read_only_ips":{"description":"S3 hosts with read-only permissions.","items":{"type":"string"},"type":"array"}},"required":["name"],"type":"object"},"BucketPolicy":{"properties":{"bucketPolicyKrn":{"description":"Unique Key Resource Name (KRN) of the bucket policy.","type":"string"},"bucketKrn":{"description":"Unique Key Resource Name (KRN) of the bucket policy.","type":"string"},"s3_read_write_ips":{"description":"S3 hosts with read/write permissions.","items":{"type":"string"},"type":"array"},"s3_read_only_ips":{"description":"S3 hosts with read-only permissions.","items":{"type":"string"},"type":"array"},"created_at":{"description":"Creation timestamp of the policy.","format":"date-time","type":"string"},"updated_at":{"description":"Last updated timestamp of the policy.","format":"date-time","type":"string"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/policy/{bucketKrn}":{"post":{"description":"Creates a new bucket policy.","parameters":[{"description":"The unique bucketKrn of the bucket policy to create.","explode":false,"in":"path","name":"bucketKrn","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketPolicyCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketPolicy"}}},"description":"Bucket policy created."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Create a Bucket Policy","tags":["BucketPolicies"]}}}}
```

## Modify a Bucket Policy

> Modifies an existing bucket policy.

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"BucketPolicyUpdate":{"properties":{"s3_read_write_ips":{"description":"S3 hosts with read/write permissions.","items":{"type":"string"},"type":"array"},"s3_read_only_ips":{"description":"S3 hosts with read-only permissions.","items":{"type":"string"},"type":"array"}},"type":"object"},"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/policy/{bucketKrn}":{"put":{"description":"Modifies an existing bucket policy.","parameters":[{"description":"The unique bucketKrn of the bucket policy.","explode":false,"in":"path","name":"bucketKrn","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BucketPolicyUpdate"}}},"required":true},"responses":{"200":{"description":"Bucket policy modified."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Modify a Bucket Policy","tags":["BucketPolicies"]}}}}
```

## Delete a Bucket Policy

> Deletes a specified bucket policy.

```json
{"openapi":"3.0.0","info":{"title":"Object Storage Bucket API","version":"1.0.0"},"tags":[],"servers":[{"url":"/"}],"security":[{},{"K-Customer-ID":[]},{},{},{},{"Authorization":[]},{},{}],"components":{"securitySchemes":{"K-Customer-ID":{"description":"Krutrim customer user id","in":"header","name":"K-Customer-ID","type":"apiKey"},"Authorization":{"bearerFormat":"JWT","description":"Authorization","scheme":"bearer","type":"http"}},"schemas":{"ErrorBadRequest":{"description":"Bad request or invalid input","properties":{"message":{"type":"string"}},"type":"object"},"ErrorUnauthorized":{"description":"Unauthorized access","properties":{"message":{"type":"string"}},"type":"object"},"ErrorNotFound":{"description":"Resource not found","properties":{"message":{"type":"string"}},"type":"object"},"ErrorInternalServerError":{"description":"Internal server error","properties":{"message":{"type":"string"}},"type":"object"},"ErrorServiceUnavailable":{"description":"Service is currently unavailable","properties":{"message":{"type":"string"}},"type":"object"}}},"paths":{"/kos/v1/buckets/policy/{bucketKrn}":{"delete":{"description":"Deletes a specified bucket policy.","parameters":[{"description":"The unique bucketKrn of the bucket policy to delete.","explode":false,"in":"path","name":"bucketKrn","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"204":{"description":"Bucket policy deleted."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBadRequest"}}},"description":"Bad request, invalid parameters"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorUnauthorized"}}},"description":"Unauthorized access"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorNotFound"}}},"description":"Bucket policy not found"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorInternalServerError"}}},"description":"Internal server error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorServiceUnavailable"}}},"description":"Service unavailable"}},"summary":"Delete a Bucket Policy","tags":["BucketPolicies"]}}}}
```


# Model Catalog API


# Finetuning API

## GET /v1/inference/checkpoints

> List all fine\_tuning checkpoints.

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/checkpoints":{"get":{"summary":"List all fine_tuning checkpoints.","tags":["finetuning","inferencing"],"responses":{"200":{"description":"Checkpoints list.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"Checkpoint name."}}}}},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"}]}}}}
```

## GET /v1/inference/checkpoints/{id}/del

> Delete the checkpoint

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/checkpoints/{id}/del":{"get":{"summary":"Delete the checkpoint","tags":["inferencing"],"responses":{"200":{"description":"Checkpoint is deleted."},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}}}}
```

## GET /v1/inference/tasks

> List inference tasks

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/tasks":{"get":{"summary":"List inference tasks","tags":["inferencing"],"responses":{"200":{"description":"Inference tasks list.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"Task information.","properties":{"name":{"type":"string","description":"Task name."},"id":{"type":"string","description":"Task ID."}}}}}}},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"}]}}}}
```

## POST /v1/inference/tasks

> Create inference task

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/tasks":{"post":{"summary":"Create inference task","tags":["inferencing"],"responses":{"200":{"description":"Inference task is created.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Task name."},"id":{"type":"string","description":"Task ID."}}}}}},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"task_name":{"type":"string","description":"Task name.","required":true},"namespace":{"type":"string","description":"Task Name.","default":"gpu-scheduler"},"priority":{"type":"integer","description":"Task priority.","required":true},"model":{"type":"string","description":"Model name.","required":true},"checkpoint":{"type":"string","description":"Checkpoint name.","required":true},"ngpu":{"type":"integer","description":"Number of GPU to be used by the inference task.","required":true}}}}}}}}}}
```

## GET /v1/inference/tasks/{id}

> Get inference task information.

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/tasks/{id}":{"get":{"summary":"Get inference task information.","tags":["inferencing"],"responses":{"200":{"description":"Inference task information.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Task name."},"namespace":{"type":"string","description":"Task namespace."},"id":{"type":"string","description":"Task ID."},"priority":{"type":"string","description":"Task priority."},"status":{"type":"string","description":"Task status."},"inference_svc_name":{"type":"string","description":"Inference service name."},"inference_svc_url":{"type":"string","description":"Inference service url."}}}}}},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}}}}
```

## GET /v1/inference/tasks/{id}/cancel

> Cancel inference task.

```json
{"openapi":"3.1.0","info":{"title":"Fine tuning service","version":"1"},"paths":{"/v1/inference/tasks/{id}/cancel":{"get":{"summary":"Cancel inference task.","tags":["inferencing"],"responses":{"200":{"description":"Inference task is canceled"},"400":{"description":"Unknown APIs.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","description":"API token."}}}}}},"parameters":[{"name":"x-user","in":"header","required":true,"schema":{"type":"string"},"description":"username"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}}}}
```


# Bhashik Speech API

## Text to Speech

> Convert input text to an audio file in the specified language and speaker voice.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Text-to-Speech"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"TTSRequest":{"type":"object","required":["input_text","input_language","input_speaker"],"properties":{"input_text":{"type":"string","description":"Input text to synthesize."},"input_language":{"$ref":"#/components/schemas/LanguageShort"},"input_speaker":{"$ref":"#/components/schemas/Speaker"}}},"LanguageShort":{"type":"string","description":"Language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"Speaker":{"type":"string","enum":["female","male"]},"TTSResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"audio_file":{"type":"string","description":"Download URL for the generated audio file."}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/tts":{"post":{"tags":["Text-to-Speech"],"summary":"Text to Speech","description":"Convert input text to an audio file in the specified language and speaker voice.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TTSRequest"}}}},"responses":{"200":{"description":"Audio file link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TTSResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Text to Speech Translation

> Translate input text from source language to target language and return synthesized speech.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Text-to-Speech"},{"name":"Translation"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"TTSTransRequest":{"type":"object","required":["input_text","src_lang_code","tgt_lang_code","input_speaker"],"properties":{"input_text":{"type":"string","description":"Input text to translate and synthesize."},"src_lang_code":{"$ref":"#/components/schemas/LanguageSrcOnlyEng"},"tgt_lang_code":{"$ref":"#/components/schemas/LanguageTarget"},"input_speaker":{"$ref":"#/components/schemas/Speaker"}}},"LanguageSrcOnlyEng":{"type":"string","enum":["eng"],"description":"Only 'eng' is supported as the source for certain translation endpoints."},"LanguageTarget":{"type":"string","description":"Target language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"Speaker":{"type":"string","enum":["female","male"]},"TTSTransResponse":{"allOf":[{"$ref":"#/components/schemas/TTSResponse"}]},"TTSResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"audio_file":{"type":"string","description":"Download URL for the generated audio file."}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/tts_trans":{"post":{"tags":["Text-to-Speech","Translation"],"summary":"Text to Speech Translation","description":"Translate input text from source language to target language and return synthesized speech.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TTSTransRequest"}}}},"responses":{"200":{"description":"Audio file link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TTSTransResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Speech to Text (upload)

> Upload a short audio file (mp3, wav) and get transcribed text.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Speech-to-Text"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"STTUploadRequest":{"type":"object","required":["file","lang_code"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file (mp3 or wav)."},"lang_code":{"$ref":"#/components/schemas/LanguageShort"}}},"LanguageShort":{"type":"string","description":"Language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"STTResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"text":{"type":"array","items":{"type":"string"},"description":"Transcribed text segments."}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/transcribe/upload":{"post":{"tags":["Speech-to-Text"],"summary":"Speech to Text (upload)","description":"Upload a short audio file (mp3, wav) and get transcribed text.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/STTUploadRequest"}}}},"responses":{"200":{"description":"Transcribed text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/STTResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Speech to Text Translation (upload)

> Upload a short audio file (mp3, wav) and get translated text.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Speech-to-Text"},{"name":"Translation"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"STTTransUploadRequest":{"type":"object","required":["file","src_lang_code","tgt_lang_code"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file (mp3 or wav)."},"src_lang_code":{"$ref":"#/components/schemas/LanguageSrcOnlyEng"},"tgt_lang_code":{"$ref":"#/components/schemas/LanguageTarget"}}},"LanguageSrcOnlyEng":{"type":"string","enum":["eng"],"description":"Only 'eng' is supported as the source for certain translation endpoints."},"LanguageTarget":{"type":"string","description":"Target language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"STTTransResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"translated_text":{"type":"string","description":"Translated text."}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/stt_trans/upload":{"post":{"tags":["Speech-to-Text","Translation"],"summary":"Speech to Text Translation (upload)","description":"Upload a short audio file (mp3, wav) and get translated text.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/STTTransUploadRequest"}}}},"responses":{"200":{"description":"Translated text","content":{"application/json":{"schema":{"$ref":"#/components/schemas/STTTransResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Speech to Speech Translation (upload)

> Upload a short audio file and receive translated synthesized speech.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Translation"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"STSUploadRequest":{"type":"object","required":["file","src_lang_code","tgt_lang_code","input_speaker"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file (mp3 or wav)."},"src_lang_code":{"$ref":"#/components/schemas/LanguageSrcOnlyEng"},"tgt_lang_code":{"$ref":"#/components/schemas/LanguageTarget"},"input_speaker":{"$ref":"#/components/schemas/Speaker"}}},"LanguageSrcOnlyEng":{"type":"string","enum":["eng"],"description":"Only 'eng' is supported as the source for certain translation endpoints."},"LanguageTarget":{"type":"string","description":"Target language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"Speaker":{"type":"string","enum":["female","male"]},"STSResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"audio_file":{"type":"string","description":"Download URL for the translated synthesized audio."}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/sts_trans/upload":{"post":{"tags":["Translation"],"summary":"Speech to Speech Translation (upload)","description":"Upload a short audio file and receive translated synthesized speech.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/STSUploadRequest"}}}},"responses":{"200":{"description":"Audio file link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/STSResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Long-duration Speech to Text (upload)

> Upload a longer audio file for asynchronous transcription; returns a request\_id that can be polled.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Speech-to-Text"},{"name":"Long-Form"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"STTUploadRequest":{"type":"object","required":["file","lang_code"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file (mp3 or wav)."},"lang_code":{"$ref":"#/components/schemas/LanguageShort"}}},"LanguageShort":{"type":"string","description":"Language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"LongFormQueuedResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"request_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["QUEUED"]}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/transcribe/lf/upload":{"post":{"tags":["Long-Form","Speech-to-Text"],"summary":"Long-duration Speech to Text (upload)","description":"Upload a longer audio file for asynchronous transcription; returns a request_id that can be polled.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/STTUploadRequest"}}}},"responses":{"200":{"description":"Job queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LongFormQueuedResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Long-duration Speech to Text Translation (upload)

> Upload a longer audio file for asynchronous speech-to-text translation; returns a request\_id that can be polled.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Translation"},{"name":"Long-Form"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"STTTransLFUploadRequest":{"type":"object","required":["file","src_lang_code","tgt_lang_code"],"properties":{"file":{"type":"string","format":"binary","description":"Long audio file (mp3 or wav)."},"src_lang_code":{"$ref":"#/components/schemas/LanguageSrcOnlyEng"},"tgt_lang_code":{"$ref":"#/components/schemas/LanguageTarget"}}},"LanguageSrcOnlyEng":{"type":"string","enum":["eng"],"description":"Only 'eng' is supported as the source for certain translation endpoints."},"LanguageTarget":{"type":"string","description":"Target language code","enum":["eng","guj","ben","hin","kan","mal","mar","tam","tel"]},"LongFormQueuedResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"request_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["QUEUED"]}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/stt_trans/lf/upload":{"post":{"tags":["Long-Form","Translation"],"summary":"Long-duration Speech to Text Translation (upload)","description":"Upload a longer audio file for asynchronous speech-to-text translation; returns a request_id that can be polled.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/STTTransLFUploadRequest"}}}},"responses":{"200":{"description":"Job queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LongFormQueuedResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Get long-duration job status

> Poll the status of a long-duration transcription/translation job and obtain the output link/text when available.

```json
{"openapi":"3.0.3","info":{"title":"Krutrim LanguageLabs APIs","version":"1.0.0"},"tags":[{"name":"Long-Form"}],"servers":[{"url":"https://cloud.olakrutrim.com/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"JobStatusResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"request_id":{"type":"string"},"file_name":{"type":"string"},"file_size_mb":{"type":"number","format":"float"},"service_type":{"type":"string","description":"Service handling the job (e.g., stttransservice)."},"status":{"type":"string","description":"Current job status (e.g., QUEUED, RUNNING, FAILED, SUCCESS)."},"output_file":{"type":"string","nullable":true,"description":"Download URL for output (e.g., .txt) if SUCCESS."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"Error":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/languagelabs/job_status/{request_id}":{"get":{"tags":["Long-Form"],"summary":"Get long-duration job status","description":"Poll the status of a long-duration transcription/translation job and obtain the output link/text when available.","parameters":[{"in":"path","name":"request_id","required":true,"schema":{"type":"string"},"description":"Request ID returned by the long-duration upload endpoint."}],"responses":{"200":{"description":"Job status payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatusResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Request ID not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Bhashik Text API

## POST /api/v1/languagelabs/language-detection

> Detect language(s) in text

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Text Services API","version":"1.0.1"},"tags":[{"name":"Language Detection","description":"Detect primary and secondary languages with confidence from input text."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Provide your API key as a Bearer token: Authorization: Bearer <KRUTRIM_API_KEY>"}},"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized — Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not Found — The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary."},"detail":{"type":"object","description":"Additional diagnostic details.","properties":{"info":{"type":"string","description":"Extra context about the error."}}}}}}},"paths":{"/api/v1/languagelabs/language-detection":{"post":{"tags":["Language Detection"],"summary":"Detect language(s) in text","operationId":"detectLanguage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Input text to analyze."}}}}}},"responses":{"200":{"description":"Detected languages with confidences.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}}}
```

## POST /api/v1/languagelabs/entity-extraction

> Extract entities and PII

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Text Services API","version":"1.0.1"},"tags":[{"name":"Entity Extraction","description":"Extract PII and named entities; optionally keywords, profanity, and task type."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Provide your API key as a Bearer token: Authorization: Bearer <KRUTRIM_API_KEY>"}},"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized — Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary."},"detail":{"type":"object","description":"Additional diagnostic details.","properties":{"info":{"type":"string","description":"Extra context about the error."}}}}}}},"paths":{"/api/v1/languagelabs/entity-extraction":{"post":{"tags":["Entity Extraction"],"summary":"Extract entities and PII","operationId":"extractEntities","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","param_list","lang_from"],"properties":{"text":{"type":"string","description":"Input text to analyze."},"lang_from":{"type":"string","description":"Language code for input text (e.g., hin, ben, mar, tam, tel, kan, mal, pan, guj).\n","enum":["hin","ben","mar","tam","tel","kan","mal","pan","guj"]},"param_list":{"type":"array","description":"Select which extractions to run. Supported: keywords, profanity, ner, task_type, pii.\n","items":{"type":"string","enum":["keywords","profanity","ner","task_type","pii"]}}}}}}},"responses":{"200":{"description":"Extracted entities and PII.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"color":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}}}}}}},"Total_entities":{"type":"integer"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## POST /api/v1/languagelabs/summarization

> Summarize text

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Text Services API","version":"1.0.1"},"tags":[{"name":"Summarization","description":"Generate a concise summary for input text."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Provide your API key as a Bearer token: Authorization: Bearer <KRUTRIM_API_KEY>"}},"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized — Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary."},"detail":{"type":"object","description":"Additional diagnostic details.","properties":{"info":{"type":"string","description":"Extra context about the error."}}}}}}},"paths":{"/api/v1/languagelabs/summarization":{"post":{"tags":["Summarization"],"summary":"Summarize text","operationId":"summarizeText","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","input_language","summary_size"],"properties":{"text":{"type":"string","description":"Text to summarize."},"input_language":{"type":"string","description":"Language code for the input text.\nSupported: eng (English), hin (Hindi), ben (Bengali), mar (Marathi), tam (Tamil),\ntel (Telugu), kan (Kannada), mal (Malayalam), pan (Punjabi), guj (Gujarati).\n","enum":["eng","hin","ben","mar","tam","tel","kan","mal","pan","guj"]},"summary_size":{"type":"integer","description":"Target summary size in words.","minimum":1}}}}}},"responses":{"200":{"description":"Summary generated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"summaryText":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## POST /api/v1/languagelabs/translation

> Translate text

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Text Services API","version":"1.0.1"},"tags":[{"name":"Translation","description":"Translate text between supported languages."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Provide your API key as a Bearer token: Authorization: Bearer <KRUTRIM_API_KEY>"}},"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized — Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary."},"detail":{"type":"object","description":"Additional diagnostic details.","properties":{"info":{"type":"string","description":"Extra context about the error."}}}}}}},"paths":{"/api/v1/languagelabs/translation":{"post":{"tags":["Translation"],"summary":"Translate text","operationId":"translateText","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","src_language","tgt_language","model"],"properties":{"text":{"type":"string","description":"Input text to translate."},"src_language":{"type":"string","description":"Source language code (e.g., eng_Latn)."},"tgt_language":{"type":"string","description":"Target language code (e.g., hin_Deva)."},"model":{"type":"string","description":"Translation model to be used.","enum":["krutrim-translate-v1.0"]}}}}}},"responses":{"200":{"description":"Translation generated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"translated_text":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}}}
```

## POST /api/v1/languagelabs/sentiment-analysis

> Analyze sentiment

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Text Services API","version":"1.0.1"},"tags":[{"name":"Sentiment Analysis","description":"Identify sentiment labels for input text."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"Provide your API key as a Bearer token: Authorization: Bearer <KRUTRIM_API_KEY>"}},"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Unauthorized — Invalid or missing API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary."},"detail":{"type":"object","description":"Additional diagnostic details.","properties":{"info":{"type":"string","description":"Extra context about the error."}}}}}}},"paths":{"/api/v1/languagelabs/sentiment-analysis":{"post":{"tags":["Sentiment Analysis"],"summary":"Analyze sentiment","operationId":"analyzeSentiment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","lang_from"],"properties":{"text":{"type":"string","description":"Input text to analyze."},"lang_from":{"type":"string","description":"Language code for input text (e.g., eng, hin, ben, mar, tam, tel, kan, mal, pan, guj).\n","enum":["eng","hin","ben","mar","tam","tel","kan","mal","pan","guj"]}}}}}},"responses":{"200":{"description":"Sentiment labels detected.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"Sentiment":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"array","items":{"type":"string"}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```


# DIS APIs

This page contains the API endpoints for all document intelligence services.

## Extract text from a document

> Upload a document (digital or scanned) in Base64 format and extract its text. Returns a \`file\_id\` to track processing status.

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Document Intelligence Services (DIS) API","version":"1.0.0"},"tags":[{"name":"Text Extraction","description":"Extract plain text from digital or scanned documents."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"paths":{"/v1/document/extract_text":{"post":{"tags":["Text Extraction"],"summary":"Extract text from a document","description":"Upload a document (digital or scanned) in Base64 format and extract its text. Returns a `file_id` to track processing status.","operationId":"extractText","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file_content","language","file_type"],"properties":{"file_content":{"type":"string","description":"Base64 encoded input document"},"language":{"type":"string","description":"Language of the input document","enum":["english"]},"file_type":{"type":"string","description":"Type of input document","enum":["Digital","Scanned"]}}}}}},"responses":{"200":{"description":"Text extraction initiated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"integer"},"data":{"type":"object","properties":{"file_id":{"type":"string","description":"The ID to track the status"},"action":{"type":"string"},"file_status":{"type":"string"},"output_type":{"type":"string"}}},"http_status":{"type":"string"},"timestamp":{"type":"integer","description":"Unix timestamp"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not Found — The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary"},"detail":{"type":"object","description":"Additional diagnostic details","properties":{"info":{"type":"string","description":"Extra context about the error"}}}}}}}}
```

## Extract structured information from a document

> Upload a document (digital or scanned) in Base64 format and extract entities such as PII, NER, or key-value pairs. Optionally specify custom keys to extract.

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Document Intelligence Services (DIS) API","version":"1.0.0"},"tags":[{"name":"Information Extraction","description":"Extract PII, NER, and key-value pairs; optionally specific keys."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"paths":{"/v1/document/extract_information":{"post":{"tags":["Information Extraction"],"summary":"Extract structured information from a document","description":"Upload a document (digital or scanned) in Base64 format and extract entities such as PII, NER, or key-value pairs. Optionally specify custom keys to extract.","operationId":"extractInformation","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file_content","language","entities","file_type"],"properties":{"file_content":{"type":"string","description":"Base64 encoded input document"},"language":{"type":"string","description":"Language of the input document","enum":["english"]},"entities":{"type":"array","description":"List of entity types to extract","items":{"type":"string","enum":["PII","NER","key_value"]}},"file_type":{"type":"string","description":"Type of input document","enum":["Digital","Scanned"]},"keys_to_extract":{"type":"array","description":"Optional list of specific keys to extract","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Information extraction initiated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"integer"},"data":{"type":"object","properties":{"file_id":{"type":"string","description":"The ID to track the status"},"action":{"type":"string"},"file_status":{"type":"string"},"output_type":{"type":"string"}}},"http_status":{"type":"string"},"timestamp":{"type":"integer","description":"Unix timestamp"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not Found — The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary"},"detail":{"type":"object","description":"Additional diagnostic details","properties":{"info":{"type":"string","description":"Extra context about the error"}}}}}}}}
```

## Summarize a document

> Upload a document (digital or scanned) in Base64 format and generate a summarized version according to the specified word count.

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Document Intelligence Services (DIS) API","version":"1.0.0"},"tags":[{"name":"Document Summarization","description":"Generate a condensed summary from an input document."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"paths":{"/v1/document/doc_summarization":{"post":{"tags":["Document Summarization"],"summary":"Summarize a document","description":"Upload a document (digital or scanned) in Base64 format and generate a summarized version according to the specified word count.","operationId":"docSummarization","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file_content","language","file_type","word_count_for_summarization"],"properties":{"file_content":{"type":"string","description":"Base64 encoded input document"},"language":{"type":"string","description":"Language of the input document","enum":["english"]},"file_type":{"type":"string","description":"Type of input document","enum":["Digital","Scanned"]},"word_count_for_summarization":{"type":"integer","description":"Target word count for summarization"}}}}}},"responses":{"200":{"description":"Document summarization initiated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"integer"},"data":{"type":"object","properties":{"file_id":{"type":"string","description":"The ID to track the status"},"action":{"type":"string"},"file_status":{"type":"string"},"output_type":{"type":"string"}}},"http_status":{"type":"string"},"timestamp":{"type":"integer","description":"Unix timestamp"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not Found — The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary"},"detail":{"type":"object","description":"Additional diagnostic details","properties":{"info":{"type":"string","description":"Extra context about the error"}}}}}}}}
```

## Mask Personally Identifiable Information in a document

> Upload a document (digital or scanned) in Base64 format and mask sensitive fields like names, positions, and other specified keys.

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Document Intelligence Services (DIS) API","version":"1.0.0"},"tags":[{"name":"PII Masking","description":"Mask personally identifiable information (PII) in documents."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"paths":{"/v1/document/PII_masking":{"post":{"tags":["PII Masking"],"summary":"Mask Personally Identifiable Information in a document","description":"Upload a document (digital or scanned) in Base64 format and mask sensitive fields like names, positions, and other specified keys.","operationId":"piiMasking","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file_content","language","file_type","keys_to_mask"],"properties":{"file_content":{"type":"string","description":"Base64 encoded input document"},"language":{"type":"string","description":"Language of the input document","enum":["english"]},"file_type":{"type":"string","description":"Type of input document","enum":["Digital","Scanned"]},"keys_to_mask":{"type":"array","description":"List of keys/fields to be masked in the document","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"PII masking initiated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"integer"},"data":{"type":"object","properties":{"file_id":{"type":"string","description":"The ID to track the status"},"action":{"type":"string"},"file_status":{"type":"string"},"output_type":{"type":"string"}}},"http_status":{"type":"string"},"timestamp":{"type":"integer","description":"Unix timestamp"},"status":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalServerError"},"502":{"$ref":"#/components/responses/BadGateway"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"responses":{"BadRequest":{"description":"Bad Request — Invalid request format or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Not Found — The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"UnprocessableEntity":{"description":"Unprocessable Entity — Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"TooManyRequests":{"description":"Too Many Requests — Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"BadGateway":{"description":"Bad Gateway — Upstream service error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ServiceUnavailable":{"description":"Service Unavailable — Try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","required":["status","message","detail"],"properties":{"status":{"type":"string","enum":["failed"]},"message":{"type":"string","description":"Human-readable error summary"},"detail":{"type":"object","description":"Additional diagnostic details","properties":{"info":{"type":"string","description":"Extra context about the error"}}}}}}}}
```

## Get document status

> Retrieve the status of a document processing request using its \`file\_id\`.

```json
{"openapi":"3.1.0","info":{"title":"Krutrim LanguageLabs — Document Intelligence Services (DIS) API","version":"1.0.0"},"tags":[{"name":"Document Status","description":"Check processing status and output for a submitted document."}],"servers":[{"url":"https://cloud.olakrutrim.com","description":"Production server"}],"paths":{"/v1/document/status":{"get":{"tags":["Document Status"],"summary":"Get document status","description":"Retrieve the status of a document processing request using its `file_id`.","operationId":"getDocumentStatus","parameters":[{"name":"file_id","in":"query","required":true,"description":"The unique ID of the uploaded document.","schema":{"type":"string"}}],"responses":{"200":{"description":"Status retrieved successfully","content":{"application/json":{}}},"422":{"description":"Failed to generate response","content":{"application/json":{}}}}}}}}
```


# Core Infra SDK

### Overview

The **Krutrim Python SDK** enables developers to interact programmatically with Krutrim Cloud services, including Compute, Networking, Storage, Security, and AI Pods.\
With a single unified client, you can create and manage resources such as VMs, VPCs, Volumes, Buckets, Security Groups, and AI workloads.

[https://github.com/ola-krutrim/Krutrim-client-python](<https://github.com/ola-krutrim/Krutrim-client-python&#xA;>)

***

### Installation

```bash
bashCopyEditpip uninstall krutrim-client-python  # optional: remove previous version
pip install krutrim-client-python    # install from PyPI
```

> **Note:** If installing from source:

```bash
bashCopyEditpython setup.py bdist_wheel
pip install dist/krutrim_client_python-<version>-py3-none-any.whl
```

***

### Authentication

```python
pythonCopyEditimport requests

url = "https://cloud.olakrutrim.com/iam/v1/signInAsRootUser"
payload = {
    "email": "<your_email>",
    "password": "<your_password>"
}
response = requests.post(url, json=payload)
access_token = response.json()["access_token"]
```

Tokens refresh every **5 minutes**.\
You should implement a token refresh mechanism for long-running scripts.

***

### Initializing the Client

```python
pythonCopyEditfrom krutrim_client_python import KrutrimClient

client = KrutrimClient(api_key=access_token)
```

***

### Services & Methods

#### 1. Networking – VPC & Subnets

| Method                                                                          | Parameters                                                                                                                                                                                                                                    | Description                     |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| `create_vpc(vpc_data: dict, x_region: str)`                                     | <p><strong>vpc\_data</strong> – dict containing <code>network</code>, <code>security\_group</code>, <code>subnet</code> details.<br><strong>x\_region</strong> – region name (<code>In-Bangalore-1</code> / <code>In-Hyderabad-1</code>).</p> | Create a new VPC.               |
| `get_vpc_task_status(task_id: str, x_region: str)`                              | <p><strong>task\_id</strong> – ID of the task.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                               | Check the status of a VPC task. |
| `retrieve_vpc(vpc_id: str, x_region: str, vpc_name: str = None)`                | <p><strong>vpc\_id</strong> – VPC ID.<br><strong>x\_region</strong> – region name.<br><strong>vpc\_name</strong> – optional name filter.</p>                                                                                                  | Get VPC details.                |
| `list_vpcs(x_region: str)`                                                      | **x\_region** – region name.                                                                                                                                                                                                                  | List all VPCs.                  |
| `delete_vpc(vpc_id: str, x_region: str)`                                        | <p><strong>vpc\_id</strong> – VPC ID.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                                        | Delete a VPC.                   |
| `create_subnet(subnet_data: dict, vpc_id: str, router_krn: str, x_region: str)` | <p><strong>subnet\_data</strong> – subnet configuration.<br><strong>vpc\_id</strong> – VPC ID.<br><strong>router\_krn</strong> – router KRN.<br><strong>x\_region</strong> – region name.</p>                                                 | Create a subnet in a VPC.       |

***

#### 2. Security Groups

| Method                                                                                                                                       | Parameters                                                                                                                                                                                                                                                           | Description                                                                                                                                                                                                                |
| -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create_security_group(name: str, description: str, vpcid: str, x_region: str)`                                                              | <p><strong>name</strong> – security group name.<br><strong>description</strong> – description.<br><strong>vpcid</strong> – VPC ID.<br><strong>x\_region</strong> – region name.</p>                                                                                  | Create a new security group.                                                                                                                                                                                               |
| `list_by_vpc(vpc_krn_identifier: str, x_region: str)`                                                                                        | <p><strong>vpc\_krn\_identifier</strong> – VPC KRN.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                                                 | List all security groups in a VPC.                                                                                                                                                                                         |
| `create_rule(direction: str, ethertype: str, protocol: str, port_range_min: int, port_range_max: int, remote_ip_prefix: str, x_region: str)` | Standard rule parameters + region.                                                                                                                                                                                                                                   | Create an inbound/outbound rule.                                                                                                                                                                                           |
| `attach_rule(ruleid: str, securityid: str, vpcid: str, x_region: str)`                                                                       | IDs + region name.                                                                                                                                                                                                                                                   | Attach a rule.                                                                                                                                                                                                             |
| `detach_rule(ruleid: str, securityid: str, vpcid: str, x_region: str)`                                                                       | IDs + region name.                                                                                                                                                                                                                                                   | Detach a rule.                                                                                                                                                                                                             |
| `delete_rule(securitygroupruleid: str, x_region: str)`                                                                                       | Rule ID + region name.                                                                                                                                                                                                                                               | Delete a rule.                                                                                                                                                                                                             |
| `delete_security_group(securitygroupid: str, x_region: str)`                                                                                 | Security group ID + region.                                                                                                                                                                                                                                          | Delete a security group.                                                                                                                                                                                                   |
| `update_port_security_groups(port_krn: str, security_groups: list[str], x_region: str)`                                                      | <p><strong>port\_krn</strong> – Port KRN (available in instance.network\_ports\[].krn).</p><p><strong>security\_groups</strong> – complete list of Security Group KRNs to retain (must not be empty).</p><p><strong>x\_region</strong> – region name.</p><p><br></p> | Updates Security Groups on a port using `PUT /api/v1/ports/{port_krn}`. This operation replaces the entire Security Group list. Include every Security Group that should remain attached; omit any that should be removed. |

***

#### 3. Compute – Instances (VMs)

| Method                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Parameters                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Description                                                                                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `create_instance(instanceName: str, instanceType: str, region: str, vpc_id: str, subnet_id: str, sshkey_name: str, security_groups: list[str], image_krn: str = None, volume_name: str =` `None, volume_size: int = None, volumetype: str = None, volumes: list[str] = None, floating_ip: bool = False, user_data: str = "", delete_on_termination: bool = True, tags: list = [], count: int = 1, port_krn: str = None, isGpu: bool = False, timeout: int = None)` | <p><strong>instanceName</strong> – VM name.instance</p><p><strong>Type</strong> – e.g. "CPU-2x-8GB"</p><p><strong>region</strong> – deployment region</p><p><strong>vpc\_id</strong> – VPC ID</p><p><strong>subnet\_id</strong> – subnet ID</p><p><strong>sshkey\_name</strong> – SSH key name</p><p><strong>security\_groups</strong> – list of Security Group KRNs</p><p><strong>For a new boot volume,</strong> provide image\_krn, volume\_name, volume\_size, volumetype (omit volumes).</p><p><strong>To boot from an existing volume</strong>, provide volumes (omit image/volume creation fields).network\_id is automatically resolved from the VPC and subnet and must not be supplied.</p> | Launches a VM **asynchronously** using `POST /vm/v1/create_instance_async`. Returns `{ message, task_id }`. Poll with `search_instances()` or `retrieve_instance()` until the VM reaches **ACTIVE**.               |
| `search_instances(vpc_id: str, x_region: str, page: int = None, limit: int = None)`                                                                                                                                                                                                                                                                                                                                                                                | <p><strong>vpc\_id</strong> – VPC ID.</p><p><strong>x\_region</strong> – region name.</p><p><strong>page</strong> – optional page number.</p><p><strong>limit</strong> – optional page size.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Search instances in a VPC using `GET /vm/v1/search_instances`. Recommended for polling asynchronous VM create/delete operations.                                                                                   |
| `retrieve_instance(krn: str, x_region: str)`                                                                                                                                                                                                                                                                                                                                                                                                                       | <p><strong>krn</strong> – Instance KRN.</p><p><strong>x\_region</strong> – region name.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Retrieve complete VM details using `GET /v1/highlvlvpc/instance`, including `network_ports[].krn`, required for Security Group and Floating IP operations.                                                         |
| `delete_instance(instanceKrn: str, deleteVolume: bool, x_region: str)`                                                                                                                                                                                                                                                                                                                                                                                             | <p><strong>instanceKrn</strong> – VM KRN.</p><p><strong>deleteVolume</strong> – delete attached boot volume.</p><p><strong>x\_region</strong> – region name.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Deletes a VM **asynchronously** using `DELETE /vm/v1/delete_instance_async`. Returns `{ message, task_id }`. Poll `search_instances()` until the VM is removed.                                                    |
| `create_instance_template(name: str, vpc_id: str, subnet_id: str, instanceType: str, sshkey_name: str, region: str, image_krn: str, volumetype: str, volume_size: int, volume_name: str, security_groups: list[str], isGpu: bool = False, user_data: str = None)`                                                                                                                                                                                                  | <p><strong>name</strong> – template name.<br><strong>vpc\_id</strong> – VPC ID.<br><strong>subnet\_id</strong> – subnet ID.<br><strong>instanceType</strong> – VM flavor.<br><strong>sshkey\_name</strong> – SSH key.<br><strong>region</strong> – deployment region.<br><strong>image\_krn</strong> – image KRN.<br><strong>volumetype</strong> – boot volume type.<br><strong>volume\_size</strong> – boot volume size.<br><strong>volume\_name</strong> – boot volume name.<br><strong>security\_groups</strong> – Security Group KRNs.</p>                                                                                                                                                        | Creates an Instance Template using `POST /vm/v1/instance-templates/create`. Returns a template object containing `template_krn`. `network_id` is resolved automatically.                                           |
| `list_instance_templates(x_region: str, page: int = None, limit: int = None)`                                                                                                                                                                                                                                                                                                                                                                                      | <p><strong>x\_region</strong> – region name.<br><strong>page</strong> – optional page number.<br><strong>limit</strong> – optional page size.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | Lists all Instance Templates using `GET /vm/v1/instance-templates/list`.                                                                                                                                           |
| `retrieve_instance_template(template_krn: str, x_region: str)`                                                                                                                                                                                                                                                                                                                                                                                                     | <p><strong>template\_krn</strong> – Instance Template KRN.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Retrieves details of an Instance Template using `GET /vm/v1/instance-templates/details`.                                                                                                                           |
| `delete_instance_template(template_krn: str, x_region: str)`                                                                                                                                                                                                                                                                                                                                                                                                       | <p><strong>template\_krn</strong> – Instance Template KRN.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | Deletes an Instance Template using `DELETE /vm/v1/instance-templates/delete`. Returns `{ "message": "Template deleted" }`.                                                                                         |
| `batch_create_vms(template_krn: str, count: int, instanceName: str, x_region: str)`                                                                                                                                                                                                                                                                                                                                                                                | <p><strong>template\_krn</strong> – Instance Template KRN.<br><strong>count</strong> – number of VMs.<br><strong>instanceName</strong> – VM name prefix.<br><strong>x\_region</strong> – region name.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Creates multiple VMs using `POST /vm/v1/batch-vm-create`. Returns `{ batch_source, job_id, message, total_count }`. **Recommended** instead of `create_instance(count > 1)` to avoid boot-volume naming conflicts. |

***

#### 4. Block Storage

| Method                                                                                                                | Parameters                                                                                            | Description                                                                                                                   |
| --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `create_volume(volumeName: str, size: int, volumeType: str, availabilityZone: str, x_region: str)`                    | Name, size (GB), type (`"standard"`/`"ssd"`), AZ, region.                                             | Create a block volume.                                                                                                        |
| `retrieve_volume(volumeId: str, x_region: str)`                                                                       | Volume ID, region.                                                                                    | Get volume details.                                                                                                           |
| `delete_volume(volumeId: str, x_region: str)`                                                                         | Volume ID, region.                                                                                    | Delete a volume.                                                                                                              |
| `list_volumes(k_tenant_id: str, x_region: str)`                                                                       | VPC KRN, region.                                                                                      | List all volumes in a VPC.                                                                                                    |
| `attach_volume(volume_id: str, instance_id: str, k_tenant_id: str, x_region: str, mount_partition: str = "/dev/vdz")` | Volume KRN, instance KRN, VPC KRN, region, mount path (default `/dev/vdz`).                           | Attach a volume to an instance. Returns `attachments[].remote_attachment_id`, needed later as `attachment_id` when detaching. |
| `detach_volume(volume_id: str, instance_id: str, attachment_id: str, k_tenant_id: str, x_region: str)`                | Volume KRN, instance KRN, attachment ID (from `attachments[].remote_attachment_id`), VPC KRN, region. | Detach a volume from an instance.                                                                                             |

***

#### 5. Object Storage

| Method                                                  | Parameters             | Description                  |
| ------------------------------------------------------- | ---------------------- | ---------------------------- |
| `create_access_keys(key_name: str, x_region: str)`      | Key name, region.      | Create a storage access key. |
| `list_access_keys()`                                    | None.                  | List all keys.               |
| `delete_access_keys(access_key_id: str, x_region: str)` | Access key ID, region. | Delete an access key.        |
| `create_bucket(bucketName: str, region: str)`           | Name, region.          | Create a bucket.             |
| `list_buckets()`                                        | None.                  | List buckets.                |
| `delete_bucket(bucketName: str, region: str)`           | Name, region.          | Delete a bucket.             |

***

#### 6. AI Pods

| Method                                                                                                             | Parameters                                                    | Description          |
| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- | -------------------- |
| `kpod.pod.create(podName: str, imageKrn: str, instanceType: str, sshKeyName: str, volumeSize: int, x_region: str)` | Name, image KRN, instance type, SSH key, volume size, region. | Create an AI Pod.    |
| `kpod.pod.update(kpod_krn: str, action: str)`                                                                      | Pod KRN, action (`"start"`, `"stop"`, `"restart"`).           | Update AI Pod state. |
| `kpod.pod.delete(kpod_krn: str)`                                                                                   | Pod KRN.                                                      | Delete AI Pod.       |


# AI Studio SDK

## Krutrim Cloud SDK Guide (Python)

### 1. Overview

The Krutrim Python SDK (`krutrim-cloud`) provides a simple and consistent interface to interact with various AI and infrastructure services offered by Krutrim Cloud. It supports synchronous and asynchronous workflows, allowing developers to integrate image generation, text completion, and speech services into their applications with ease.

Supported Python Versions: **3.10 – 3.12**\
Package: <https://pypi.org/project/krutrim-cloud>

***

### 2. Installation

Install the SDK via pip:

```bash
pip install krutrim-cloud
```

#### System Dependencies

Some modules require `ffmpeg` and `ffprobe` to be available in your environment:

```bash
# macOS (with Homebrew)
brew install ffmpeg

# Ubuntu/Debian
sudo apt-get install ffmpeg
```

***

### 3. Authentication

You need an API key to authenticate your requests. This can be provided as an environment variable or passed directly into the client.

#### Environment Variable (Recommended)

```bash
export KRUTRIM_CLOUD_API_KEY="your_api_key_here"
```

#### Manual Key Injection

```python
from krutrim_cloud import KrutrimCloud
client = KrutrimCloud(api_key="your_api_key_here")
```

***

### 4. Client Initialization

#### Synchronous Client

```python
from krutrim_cloud import KrutrimCloud
client = KrutrimCloud()
```

#### Asynchronous Client

```python
from krutrim_cloud import KrutrimCloudAsync
client = KrutrimCloudAsync()
```

***

### 5. Core Functionalities

#### 5.1 Image Generation (Diffusion)

```python
response = client.images.generations.diffusion(
    model_name="diffusion1XL",
    image_height=1024,
    image_width=1024,
    prompt="a cyberpunk cityscape at night"
)

print(response.generated_images)
```

#### 5.2 Text Completion

```python
response = client.texts.completions.bhashini(
    prompt="Write a short story about a robot and a child.",
    language="en"
)
print(response.generated_text)
```

#### 5.3 Speech APIs (DIS / Bhashik Speech)

```python
response = client.speech.tts.bhashik(
    text="Namaste, Krutrim Cloud!",
    voice="hi_female_1"
)

with open("output.mp3", "wb") as f:
    f.write(response.audio)
```

***

### 6. Error Handling

API responses may raise exceptions for invalid input, network issues, or internal errors.

Basic handling:

```python
try:
    response = client.texts.completions.bhashini(prompt="Hello")
except Exception as e:
    print(f"Error: {str(e)}")
```

***

### 7. Using Async Workflows

```python
import asyncio
from krutrim_cloud import KrutrimCloudAsync

async def run():
    client = KrutrimCloudAsync()
    result = await client.images.generations.diffusion(
        model_name="diffusion1XL",
        image_height=512,
        image_width=512,
        prompt="a futuristic AI city"
    )
    print(result.generated_images)

asyncio.run(run())
```

***

### 8. Examples & Sample Projects

Explore example notebooks and scripts:

* [Basic Inference](https://github.com/ola-krutrim/krutrim-cloud-python/tree/main/examples)
* \[Fine-Tuning (Coming Soon)]
* \[CLI Wrapper (WIP)]

***

### 9. Versioning & Updates

To upgrade the SDK:

```bash
pip install --upgrade krutrim-cloud
```

Check the [GitHub repo](https://github.com/ola-krutrim/krutrim-cloud-python) for changelogs and release notes.

***

### 10. Support & Contribution

* For issues, submit a GitHub Issue [here](https://github.com/ola-krutrim/krutrim-cloud-python/issues)
* For API key access, contact the Krutrim team
* For feedback or enhancements, reach out via your internal Slack or community portal

***


# Load Balancer SDK

## POST /v3/highlvl/create\_load\_balancer\_orchestration

> Create Load Balancer Orchestration

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Load Balancer Lifecycle (v3)","description":"Orchestration and core management of Load Balancer resources."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/create_load_balancer_orchestration":{"post":{"tags":["Load Balancer Lifecycle (v3)"],"summary":"Create Load Balancer Orchestration","parameters":[{"$ref":"#/components/parameters/XRegion"},{"$ref":"#/components/parameters/KCustomerId"},{"$ref":"#/components/parameters/XAccountId"},{"$ref":"#/components/parameters/Authorization"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LBOrchestrationRequest"}}}},"responses":{"202":{"description":"Orchestration task accepted."}}}}},"components":{"parameters":{"XRegion":{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}},"KCustomerId":{"name":"k-customer-id","in":"header","required":true,"schema":{"type":"string"}},"XAccountId":{"name":"x-account-id","in":"header","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}},"schemas":{"LBOrchestrationRequest":{"type":"object","properties":{"loadbalancer_data":{"type":"object"},"listeners":{"type":"array","items":{"type":"object"}}}}}}}
```

## POST /v3/highlvl/update\_load\_balancer/{lb\_krn}

> Update Load Balancer

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Load Balancer Lifecycle (v3)","description":"Orchestration and core management of Load Balancer resources."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/update_load_balancer/{lb_krn}":{"post":{"tags":["Load Balancer Lifecycle (v3)"],"summary":"Update Load Balancer","parameters":[{"name":"lb_krn","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/XRegion"},{"$ref":"#/components/parameters/Authorization"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLoadBalancerRequest"}}}},"responses":{"200":{"description":"Load balancer updated successfully."}}}}},"components":{"parameters":{"XRegion":{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}},"schemas":{"UpdateLoadBalancerRequest":{"type":"object","properties":{"lb_krn":{"type":"string"},"loadbalancer_data":{"type":"object"},"listeners":{"type":"array","items":{"type":"object"}}}}}}}
```

## DELETE /v3/highlvl/loadbalancer/{lb\_krn}

> Delete Load Balancer

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Load Balancer Lifecycle (v3)","description":"Orchestration and core management of Load Balancer resources."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/loadbalancer/{lb_krn}":{"delete":{"tags":["Load Balancer Lifecycle (v3)"],"summary":"Delete Load Balancer","parameters":[{"name":"lb_krn","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/XRegion"},{"$ref":"#/components/parameters/Authorization"}],"responses":{"204":{"description":"Deletion initiated."}}}}},"components":{"parameters":{"XRegion":{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v3/highlvl/fetch\_payload\_multiple/{lb\_krn}

> Fetch Detailed LB Payload

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/fetch_payload_multiple/{lb_krn}":{"get":{"tags":["Discovery & Monitoring"],"summary":"Fetch Detailed LB Payload","parameters":[{"name":"lb_krn","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Full configuration payload returned."}}}}},"components":{"parameters":{"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v3/highlvl/get\_lb\_list\_new/{vpc\_krn}

> List Load Balancers by VPC

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/get_lb_list_new/{vpc_krn}":{"get":{"tags":["Discovery & Monitoring"],"summary":"List Load Balancers by VPC","parameters":[{"name":"vpc_krn","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"List of load balancers."}}}}},"components":{"parameters":{"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v3/highlvl/task\_status/{task\_id}

> Get Task Status

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v3/highlvl/task_status/{task_id}":{"get":{"tags":["Discovery & Monitoring"],"summary":"Get Task Status","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Current task progress."}}}}},"components":{"parameters":{"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## POST /v1/highlvl/create\_target\_group

> Create Target Group

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Target Group Management (v1)","description":"Creation, updates, and deletion of backend Target Groups."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/create_target_group":{"post":{"tags":["Target Group Management (v1)"],"summary":"Create Target Group","parameters":[{"$ref":"#/components/parameters/XRegion"},{"$ref":"#/components/parameters/Authorization"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TargetGroupRequest"}}}},"responses":{"201":{"description":"Target group created."}}}}},"components":{"parameters":{"XRegion":{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}},"schemas":{"TargetGroupRequest":{"type":"object","properties":{"vpc_id":{"type":"string"},"target_group_name":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"protocol_port":{"type":"integer"},"weight":{"type":"integer"}}}},"health_monitor":{"type":"object","properties":{"h_type":{"type":"string"},"timeout":{"type":"integer"},"delay":{"type":"integer"},"url_path":{"type":"string"}}}}}}}}
```

## POST /v1/highlvl/updatetg

> Update Target Group Members/Health

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Target Group Management (v1)","description":"Creation, updates, and deletion of backend Target Groups."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/updatetg":{"post":{"tags":["Target Group Management (v1)"],"summary":"Update Target Group Members/Health","parameters":[{"$ref":"#/components/parameters/XRegion"},{"$ref":"#/components/parameters/Authorization"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TargetGroupRequest"}}}},"responses":{"200":{"description":"Target group updated."}}}}},"components":{"parameters":{"XRegion":{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}},"schemas":{"TargetGroupRequest":{"type":"object","properties":{"vpc_id":{"type":"string"},"target_group_name":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"protocol_port":{"type":"integer"},"weight":{"type":"integer"}}}},"health_monitor":{"type":"object","properties":{"h_type":{"type":"string"},"timeout":{"type":"integer"},"delay":{"type":"integer"},"url_path":{"type":"string"}}}}}}}}
```

## DELETE /v1/highlvl/target\_group

> Delete Target Group

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Target Group Management (v1)","description":"Creation, updates, and deletion of backend Target Groups."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/target_group":{"delete":{"tags":["Target Group Management (v1)"],"summary":"Delete Target Group","parameters":[{"$ref":"#/components/parameters/VpcIdQuery"},{"name":"target_group_name","in":"query","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Target group deleted."}}}}},"components":{"parameters":{"VpcIdQuery":{"name":"vpc_id","in":"query","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v1/highlvl/get\_tg\_list

> Get Full TG List

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/get_tg_list":{"get":{"tags":["Discovery & Monitoring"],"summary":"Get Full TG List","parameters":[{"$ref":"#/components/parameters/VpcIdQuery"},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Comprehensive list of target groups."}}}}},"components":{"parameters":{"VpcIdQuery":{"name":"vpc_id","in":"query","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v1/highlvl/get\_target\_groups

> Get Detailed Target Groups

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/get_target_groups":{"get":{"tags":["Discovery & Monitoring"],"summary":"Get Detailed Target Groups","parameters":[{"$ref":"#/components/parameters/VpcIdQuery"},{"name":"target_group_name","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Detailed TG info."}}}}},"components":{"parameters":{"VpcIdQuery":{"name":"vpc_id","in":"query","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## GET /v1/highlvl/get\_target\_group\_names

> Get TG Names Only

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"tags":[{"name":"Discovery & Monitoring","description":"Status tracking and resource listing endpoints."}],"servers":[{"url":"https://r1.staging.olakrutrim.com","description":"Staging Environment"}],"paths":{"/v1/highlvl/get_target_group_names":{"get":{"tags":["Discovery & Monitoring"],"summary":"Get TG Names Only","parameters":[{"$ref":"#/components/parameters/VpcIdQuery"},{"$ref":"#/components/parameters/Authorization"}],"responses":{"200":{"description":"Array of strings containing TG names."}}}}},"components":{"parameters":{"VpcIdQuery":{"name":"vpc_id","in":"query","required":true,"schema":{"type":"string"}},"Authorization":{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}}}}
```

## The LBOrchestrationRequest object

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"components":{"schemas":{"LBOrchestrationRequest":{"type":"object","properties":{"loadbalancer_data":{"type":"object"},"listeners":{"type":"array","items":{"type":"object"}}}}}}}
```

## The UpdateLoadBalancerRequest object

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"components":{"schemas":{"UpdateLoadBalancerRequest":{"type":"object","properties":{"lb_krn":{"type":"string"},"loadbalancer_data":{"type":"object"},"listeners":{"type":"array","items":{"type":"object"}}}}}}}
```

## The TargetGroupRequest object

```json
{"openapi":"3.0.0","info":{"title":"Krutrim Load Balancer Orchestration API","version":"1.0.0"},"components":{"schemas":{"TargetGroupRequest":{"type":"object","properties":{"vpc_id":{"type":"string"},"target_group_name":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"protocol_port":{"type":"integer"},"weight":{"type":"integer"}}}},"health_monitor":{"type":"object","properties":{"h_type":{"type":"string"},"timeout":{"type":"integer"},"delay":{"type":"integer"},"url_path":{"type":"string"}}}}}}}}
```


# Krutrim Kubernetes System SDK

## POST /v1/kks/clusters

> Create Cluster

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Cluster":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"resourcesVpcConfig":{"type":"object","properties":{"vpcKrn":{"type":"string"},"subnetKrns":{"type":"string"}}},"kubernetesNetworkConfig":{"type":"object","properties":{"podIpv4Cidr":{"type":"string"},"serviceIpv4Cidr":{"type":"string"}}}}}}},"paths":{"/v1/kks/clusters":{"post":{"summary":"Create Cluster","tags":["Clusters"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"}}}},"responses":{"201":{"description":"Created"}}}}}}
```

## POST /v1/kks/clusters/{clusterKrn}/node-groups

> Create Nodegroup

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Nodegroup":{"type":"object","properties":{"name":{"type":"string"},"instanceTypes":{"type":"string"},"diskSize":{"type":"integer"},"scalingConfig":{"type":"object","properties":{"minSize":{"type":"integer"},"maxSize":{"type":"integer"},"desiredSize":{"type":"integer"}}},"subnetsKrn":{"type":"string"},"remoteAccess":{"type":"object","properties":{"sshKeyKrn":{"type":"string"},"sourceSecurityGroupsKrns":{"type":"array","items":{"type":"string"}}}},"nodeRepairConfig":{"type":"object","properties":{"enabled":{"type":"boolean"}}}}}}},"paths":{"/v1/kks/clusters/{clusterKrn}/node-groups":{"post":{"summary":"Create Nodegroup","tags":["Node Groups"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Nodegroup"}}}},"responses":{"201":{"description":"Created"}}}}}}
```

## GET /v1/kks/flavors

> List flavors

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/flavors":{"get":{"summary":"List flavors","tags":["Metadata"],"responses":{"200":{"description":"Success"}}}}}}
```

## POST /v1/kks/clusters/{clusterKrn}/addons

> Install Addon

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/addons":{"post":{"summary":"Install Addon","tags":["Addons"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"addonName":{"type":"string"}}}}}},"responses":{"201":{"description":"Installed"}}}}}}
```

## GET /v1/kks/addons

> List All addons

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/addons":{"get":{"summary":"List All addons","tags":["Metadata"],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /v1/kks/clusters/{clusterKrn}/kubeconfig

> Retrieve kubeconfig

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/kubeconfig":{"get":{"summary":"Retrieve kubeconfig","tags":["Clusters"],"responses":{"200":{"description":"kubeconfig file content"}}}}}}
```

## GET /v1/kks/clusters

> Get ALL clusters

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters":{"get":{"summary":"Get ALL clusters","tags":["Clusters"],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /v1/kks/clusters/{clusterKrn}

> Cluster by Cluster KRN

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}":{"get":{"summary":"Cluster by Cluster KRN","tags":["Clusters"],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /v1/kks/clusters/{clusterKrn}/node-groups

> List All NodeGroups

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/node-groups":{"get":{"summary":"List All NodeGroups","tags":["Node Groups"],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}

> GET Nodegroup Details

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}":{"get":{"summary":"GET Nodegroup Details","tags":["Node Groups"],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /v1/kks/clusters/{clusterKrn}/addons

> List Cluster Addons

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/addons":{"get":{"summary":"List Cluster Addons","tags":["Addons"],"responses":{"200":{"description":"Success"}}}}}}
```

## DELETE /v1/kks/clusters/{clusterKrn}

> Delete cluster

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}":{"delete":{"summary":"Delete cluster","tags":["Clusters"],"responses":{"204":{"description":"Deleted"}}}}}}
```

## DELETE /v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}

> Delete Nodegroup

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}":{"delete":{"summary":"Delete Nodegroup","tags":["Node Groups"],"responses":{"204":{"description":"Deleted"}}}}}}
```

## DELETE /v1/kks/clusters/{clusterKrn}/addons/{addonKrn}

> Delete Addon

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/addons/{addonKrn}":{"delete":{"summary":"Delete Addon","tags":["Addons"],"responses":{"204":{"description":"Deleted"}}}}}}
```

## POST /v1/kks/clusters/{clusterKrn}/updates

> Upgrade cluster

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/updates":{"post":{"summary":"Upgrade cluster","tags":["Clusters"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"}}}}}},"responses":{"200":{"description":"Upgrade initiated"}}}}}}
```

## PUT /v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}

> Upgrade nodegroup

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"servers":[{"url":"http://10.230.150.171","description":"Production Server"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/kks/clusters/{clusterKrn}/node-groups/{nodegroupKrn}":{"put":{"summary":"Upgrade nodegroup","tags":["Node Groups"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"scalingConfig":{"type":"object","properties":{"minSize":{"type":"integer"},"maxSize":{"type":"integer"},"desiredSize":{"type":"integer"}}}}}}}},"responses":{"200":{"description":"Updated"}}}}}}
```

## The Cluster object

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"components":{"schemas":{"Cluster":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"resourcesVpcConfig":{"type":"object","properties":{"vpcKrn":{"type":"string"},"subnetKrns":{"type":"string"}}},"kubernetesNetworkConfig":{"type":"object","properties":{"podIpv4Cidr":{"type":"string"},"serviceIpv4Cidr":{"type":"string"}}}}}}}}
```

## The Nodegroup object

```json
{"openapi":"3.0.0","info":{"title":"KKS - Cloud - public Prod","version":"1.0.0"},"components":{"schemas":{"Nodegroup":{"type":"object","properties":{"name":{"type":"string"},"instanceTypes":{"type":"string"},"diskSize":{"type":"integer"},"scalingConfig":{"type":"object","properties":{"minSize":{"type":"integer"},"maxSize":{"type":"integer"},"desiredSize":{"type":"integer"}}},"subnetsKrn":{"type":"string"},"remoteAccess":{"type":"object","properties":{"sshKeyKrn":{"type":"string"},"sourceSecurityGroupsKrns":{"type":"array","items":{"type":"string"}}}},"nodeRepairConfig":{"type":"object","properties":{"enabled":{"type":"boolean"}}}}}}}}
```


# Key Certificate Manager SDK

## POST /certs/import

> 1\. Import Certificate

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/import":{"post":{"summary":"1. Import Certificate","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"certFile":{"type":"string","format":"binary"},"name":{"type":"string"},"tags":{"type":"string"},"flag":{"type":"string"}}}}}},"responses":{"200":{"description":"Success"}}}}}}
```

## GET /certs/list

> 2\. List Certificates

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/list":{"get":{"summary":"2. List Certificates","parameters":[{"name":"vpcId","in":"query","required":true,"schema":{"type":"string"}},{"name":"lbtype","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /certs/detail

> 3\. Get Certificate by ID

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/detail":{"get":{"summary":"3. Get Certificate by ID","parameters":[{"name":"certId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}}}}
```

## DELETE /certs/delete/{pathCertId}

> 4\. Delete Certificate

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/delete/{pathCertId}":{"delete":{"summary":"4. Delete Certificate","parameters":[{"name":"pathCertId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}}}}
```

## GET /certs/expiringIn

> 5\. Get Expiring Certificates

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/expiringIn":{"get":{"summary":"5. Get Expiring Certificates","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string"}},{"name":"vpcId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}}}}
```

## PUT /certs/tags/{pathCertId}

> 6\. Update Tags (JSON)

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/tags/{pathCertId}":{"put":{"summary":"6. Update Tags (JSON)","parameters":[{"name":"pathCertId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Success"}}}}}}
```

## GET /certs/tags

> 7\. Get Tag Value

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/tags":{"get":{"summary":"7. Get Tag Value","parameters":[{"name":"certId","in":"query","required":true,"schema":{"type":"string"}},{"name":"tagName","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}}}}
```

## PUT /certs/update/{pathCertId}

> 8\. Update Certificate Bundle (Binary)

```json
{"openapi":"3.0.0","info":{"title":"Key Certificate Manager (KCM) API","version":"1.11.0"},"servers":[{"url":"http://10.230.150.171/kcm/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/certs/update/{pathCertId}":{"put":{"summary":"8. Update Certificate Bundle (Binary)","parameters":[{"name":"pathCertId","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Vpc-Id","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"certFile":{"type":"string","format":"binary"},"flag":{"type":"string"}}}}}},"responses":{"200":{"description":"Success"}}}}}}
```


# Auto Scaling Group SDK

## POST /asg/v1

> Create Auto Scaling Group

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AsgCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"instanceTypeId":{"type":"string"},"region":{"type":"string"},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"subnet_id":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"asg_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"},"tags":{"type":"array","items":{}},"save_as_template":{"type":"boolean"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}},"paths":{"/asg/v1":{"post":{"summary":"Create Auto Scaling Group","operationId":"createAsg","parameters":[{"name":"x-region","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsgCreateRequest"}}}},"responses":{"200":{"description":"ASG created"}}}}}}
```

## POST /asg/v1/update\_asg

> Update Auto Scaling Group

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AsgUpdateRequest":{"allOf":[{"type":"object","properties":{"asg_krn":{"type":"string"}}},{"$ref":"#/components/schemas/AsgCreateRequest"}]},"AsgCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"instanceTypeId":{"type":"string"},"region":{"type":"string"},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"subnet_id":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"asg_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"},"tags":{"type":"array","items":{}},"save_as_template":{"type":"boolean"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}},"paths":{"/asg/v1/update_asg":{"post":{"summary":"Update Auto Scaling Group","operationId":"updateAsg","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsgUpdateRequest"}}}},"responses":{"200":{"description":"ASG updated"}}}}}}
```

## POST /asg/v1/upscale

> Upscale ASG

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AsgUpscaleRequest":{"type":"object","properties":{"asg_krn":{"type":"string"},"vpc_krn":{"type":"string"},"desired_vm_count":{"type":"integer"},"attach_floating_ip":{"type":"boolean"}}}}},"paths":{"/asg/v1/upscale":{"post":{"summary":"Upscale ASG","operationId":"upscaleAsg","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsgUpscaleRequest"}}}},"responses":{"200":{"description":"Upscale triggered"}}}}}}
```

## POST /asg/v1/downscale

> Downscale ASG

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AsgDownscaleRequest":{"type":"object","properties":{"asg_krn":{"type":"string"},"count":{"type":"integer"}}}}},"paths":{"/asg/v1/downscale":{"post":{"summary":"Downscale ASG","operationId":"downscaleAsg","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsgDownscaleRequest"}}}},"responses":{"200":{"description":"Downscale triggered"}}}}}}
```

## GET /asg/v1/retrieve\_asg

> Retrieve ASG

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/asg/v1/retrieve_asg":{"get":{"summary":"Retrieve ASG","operationId":"retrieveAsg","parameters":[{"name":"asg_krn","in":"query","schema":{"type":"string"}},{"name":"asg_name","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer"}},{"name":"size","in":"query","required":true,"schema":{"type":"integer"}},{"name":"x-region","in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"ASG retrieved"}}}}}}
```

## GET /v1/asg/get\_asg\_krn

> Get ASG KRN by VPC

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/v1/asg/get_asg_krn":{"get":{"summary":"Get ASG KRN by VPC","operationId":"getAsgKrn","parameters":[{"name":"vpc_krn","in":"query","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer"}},{"name":"size","in":"query","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"ASG KRN list"}}}}}}
```

## DELETE /asg/v1/delete\_asg/{asg\_krn}

> Delete ASG

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/asg/v1/delete_asg/{asg_krn}":{"delete":{"summary":"Delete ASG","operationId":"deleteAsg","parameters":[{"name":"asg_krn","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ASG deleted"}}}}}}
```

## GET /asg/v1/get-launch-template

> Get Launch Templates

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/asg/v1/get-launch-template":{"get":{"summary":"Get Launch Templates","operationId":"getLaunchTemplates","parameters":[{"name":"vpc_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer"}},{"name":"size","in":"query","required":true,"schema":{"type":"integer"}},{"name":"x-region","in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"Templates list"}}}}}}
```

## POST /asg/v1/create-launch-template

> Create Launch Template

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"LaunchTemplateCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"region":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"subnet_id":{"type":"string"},"template_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"qos":{"type":"object","additionalProperties":true},"volumeType":{"type":"string"},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}},"paths":{"/asg/v1/create-launch-template":{"post":{"summary":"Create Launch Template","operationId":"createLaunchTemplate","parameters":[{"name":"x_region","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchTemplateCreateRequest"}}}},"responses":{"200":{"description":"Launch template created"}}}}}}
```

## POST /asg/v1/update-launch-template

> Update Launch Template

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"LaunchTemplateUpdateRequest":{"type":"object","properties":{"vm_volume_disk_size":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"bootVolumeSize":{"type":"string"},"qos":{"type":"object","additionalProperties":true},"policy":{"type":"array","items":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"},"ScaleOutThreshold":{"type":"integer"},"ScaleInThreshold":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}}}},"paths":{"/asg/v1/update-launch-template":{"post":{"summary":"Update Launch Template","operationId":"updateLaunchTemplate","parameters":[{"name":"template_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"template_name","in":"query","required":true,"schema":{"type":"string"}},{"name":"x_region","in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchTemplateUpdateRequest"}}}},"responses":{"200":{"description":"Launch template updated"}}}}}}
```

## POST /asg/v1/delete-launch-template

> Delete Launch Template

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"servers":[{"url":"https://r1.staging.olakrutrim.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"paths":{"/asg/v1/delete-launch-template":{"post":{"summary":"Delete Launch Template","operationId":"deleteLaunchTemplate","parameters":[{"name":"template_id","in":"query","required":true,"schema":{"type":"string"}},{"name":"template_name","in":"query","required":true,"schema":{"type":"string"}},{"name":"version","in":"query","required":true,"schema":{"type":"integer"}},{"name":"x-region","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Launch template deleted"}}}}}}
```

## The AsgCreateRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"AsgCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"instanceTypeId":{"type":"string"},"region":{"type":"string"},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"subnet_id":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"asg_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"},"tags":{"type":"array","items":{}},"save_as_template":{"type":"boolean"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}}
```

## The AsgUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"AsgUpdateRequest":{"allOf":[{"type":"object","properties":{"asg_krn":{"type":"string"}}},{"$ref":"#/components/schemas/AsgCreateRequest"}]},"AsgCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"instanceTypeId":{"type":"string"},"region":{"type":"string"},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"subnet_id":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"asg_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"},"tags":{"type":"array","items":{}},"save_as_template":{"type":"boolean"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}}
```

## The AsgUpscaleRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"AsgUpscaleRequest":{"type":"object","properties":{"asg_krn":{"type":"string"},"vpc_krn":{"type":"string"},"desired_vm_count":{"type":"integer"},"attach_floating_ip":{"type":"boolean"}}}}}}
```

## The AsgDownscaleRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"AsgDownscaleRequest":{"type":"object","properties":{"asg_krn":{"type":"string"},"count":{"type":"integer"}}}}}}
```

## The LaunchTemplateCreateRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"LaunchTemplateCreateRequest":{"type":"object","properties":{"vpc_krn":{"type":"string"},"instanceName":{"type":"string"},"instanceType":{"type":"string"},"region":{"type":"string"},"security_groups":{"type":"array","items":{"type":"string"}},"sshkey_name":{"type":"string"},"vm_volume_disk_size":{"type":"string"},"volumeName":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"image_krn":{"type":"string"},"network_krn":{"type":"string"},"attach_floating_ip":{"type":"boolean"},"subnet_id":{"type":"string"},"template_name":{"type":"string"},"policy":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"qos":{"type":"object","additionalProperties":true},"volumeType":{"type":"string"},"min":{"type":"integer"},"max":{"type":"integer"},"bootVolumeSize":{"type":"string"}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}},"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}}
```

## The LaunchTemplateUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"LaunchTemplateUpdateRequest":{"type":"object","properties":{"vm_volume_disk_size":{"type":"string"},"volumeSize":{"type":"array","items":{"$ref":"#/components/schemas/Volume"}},"bootVolumeSize":{"type":"string"},"qos":{"type":"object","additionalProperties":true},"policy":{"type":"array","items":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"},"ScaleOutThreshold":{"type":"integer"},"ScaleInThreshold":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}},"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}}}}}
```

## The Volume object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"Volume":{"type":"object","properties":{"count":{"type":"integer"},"volumeName":{"type":"string","nullable":true},"volumeSize":{"type":"integer"},"volumeType":{"type":"string"}}}}}}
```

## The Policy object

```json
{"openapi":"3.0.3","info":{"title":"ASG Service API","version":"1.0.0"},"components":{"schemas":{"Policy":{"type":"object","properties":{"PredefinedMetricSpecification":{"type":"object","properties":{"PredefinedMetricType":{"type":"string"}}},"UpScaleTargetValue":{"type":"integer"},"DownScaleTargetValue":{"type":"integer"},"ScaleOutCooldown":{"type":"integer"},"ScaleInCooldown":{"type":"integer"}}}}}}
```


# DNS SDK


# Terraform Provider Krutrim

### OverView

The Terraform Provider for Krutrim allows you to manage Krutrim Cloud resources using Infrastructure as Code (IaC). This helps automate provisioning and ensures consistency across environments.

[https://registry.terraform.io/providers/ola-krutrim/krutrim/0.1.2](<https://registry.terraform.io/providers/ola-krutrim/krutrim/0.1.2&#xA;>)

### Key Benefits

* Infrastructure as Code for Krutrim Cloud
* Automated provisioning and scaling
* Consistent and repeatable deployments
* Easy integration with CI/CD pipelines

### What You’ll Learn

* How to install and configure the provider
* How to create and manage resources
* Best practices for usage

### Documentation Structure

* Getting Started
* Installation & Setup
* Authentication
* Resources & Usage
* Examples
* Best Practices


# Getting Started

Prerequisites

* Terraform (v1.x or above)
* Krutrim Cloud account
* API credentials

### Quick Start

1. Install Terraform
2. Configure provider
3. Initialize Terraform
4. Apply configuration

### Basic Workflow

* Write configuration
* Run `terraform init`
* Run `terraform plan`
* Run `terraform apply`


# Installation & Setup

### Provider Installation

Add this to your Terraform file:

```
terraform {
  required_providers {
    krutrim = {
      source  = "krutrim/krutrim"
      version = ">= 1.0.0"
    }
  }
}
```

### Initialize Terraform

```
terraform init
```

### Verify Installation

```
terraform providers
```


# Authentication

### API Key Setup

Set your API key:

```
export KRUTRIM_API_KEY="your_api_key"
```

### Alternative Method

```
provider "krutrim" {
  api_key = var.api_key
}
```

### Best Practices

* Do not hardcode API keys
* Use environment variables
* Rotate keys regularly


# Resources & Usage

### Overview

The provider allows you to manage different Krutrim Cloud resources.

### Example Resource

```
resource "krutrim_instance" "example" {
  name          = "test-instance"
  image         = "ubuntu-22.04"
  instance_type = "gpu.large"
}
```

### Common Resource Types

* Compute Instances
* Storage
* Networking

### Lifecycle Actions

* Create
* Update
* Delete


# Examples

### Basic Instance

```
provider "krutrim" {}

resource "krutrim_instance" "vm" {
  name          = "demo-instance"
  image         = "ubuntu-22.04"
  instance_type = "cpu.medium"
}
```

### GPU Instance

```
resource "krutrim_instance" "gpu_vm" {
  name          = "gpu-instance"
  image         = "ubuntu-22.04"
  instance_type = "gpu.large"
}
```

### Run Commands

```
terraform init
terraform apply
```


# Best Practices

### Code Organization

* Use modules
* Separate environments (dev/staging/prod)

### Security

* Use a secrets manager
* Avoid committing sensitive data

### State Management

* Use remote backend
* Enable state locking

### Naming Conventions

* Keep names consistent
* Add environment prefixes


# Compliance Certifications

\# Compliance Certifications

<br>

This page documents Krutrim Cloud’s \*\*security and compliance posture\*\*.

<br>

All certifications, attestations, and regulatory alignments listed here describe Krutrim Cloud’s adherence to recognized standards for data protection, operational security, and risk management.

<br>

\---

<br>

\## Scope of This Page

<br>

This document is a \*\*placeholder\*\* of the documentation revamp.

<br>

\- Detailed certification reports, audit letters, or control mappings are \*\*not included\*\* here.

\- Certification availability may vary by \*\*region, service, or deployment model\*\*.

\- This page acts as a \*\*single reference location\*\* for compliance-related information.

<br>

\---

<br>

\## Typical Certifications & Standards

<br>

The following categories are expected to be documented here once finalized:

<br>

\- Information security management standards &#x20;

\- Data protection and privacy regulations &#x20;

\- Cloud security and operational controls &#x20;

\- Industry-specific compliance frameworks &#x20;

<br>

\> Actual certification names, versions, and coverage will be added and maintained manually.

<br>

\---

<br>

\## Usage Guidance

<br>

Customers may use this section to:

<br>

\- Perform vendor risk assessments &#x20;

\- Support internal or external audits &#x20;

\- Validate regulatory alignment for workloads deployed on Krutrim Cloud &#x20;

<br>

For formal compliance confirmation or documentation requests, contact Krutrim Cloud support or sales.

<br>

\---

\
\ <br>


# 12th September 2025

### 🚀 Krutrim Cloud Update — Now Live: Persistent Block Storage, Network Services, and Enhanced Compute Capabilities

We're thrilled to announce the public release of several foundational cloud infrastructure services on **Krutrim Cloud**. This release significantly enhances your ability to run scalable, reliable, and production-grade workloads with deeper control over compute, storage, and networking.

***

#### 🖥️ Enhanced Virtual Machines (Compute)

Krutrim Virtual Machines now come with extended configuration capabilities:

* **Attach Block Storage Volumes** to your VMs, allowing you to separate compute and storage for improved performance and data persistence.
* **Custom Network Setup**: When launching a VM, you can now specify the Virtual Private Cloud (VPC), Subnet, and Static IP address to place the instance exactly where you want it in your network.
* **Security Groups**: Define firewall rules that control traffic to and from your VM instances, adding a critical layer of security.

These enhancements make Krutrim VMs more flexible and secure, giving you the building blocks for running multi-tier applications and services in production.

***

#### 💾 Block Storage as a Service

We’re introducing Krutrim Block Storage — durable, high-performance SSD volumes designed for persistent data:

* **Volumes**: Provision and attach General Purpose or IOPS-Optimized SSD volumes to one or more VMs. Volumes remain available even when VMs are stopped or deleted.
* **Snapshots**: Create instant, point-in-time snapshots of your volumes for data protection or migration. Snapshots can be used to create new volumes as needed.
* **Backups (Scheduled & On-Demand)**: Automate backups of your volumes with configurable retention policies. Easily restore data in case of failure or accidental deletion.

Whether you're running databases, applications, or file systems, Block Storage helps ensure your data is safe, scalable, and easy to manage.

***

#### 🌐 Full-Featured Network Services

We’re also launching a suite of Network Services to give you full control over how your workloads connect:

* **Virtual Private Cloud (VPC)**: Launch resources in isolated, logically segmented networks. Define IP ranges and keep workloads secure and private.
* **Subnets**: Divide your VPC into subnets across availability zones for high availability and fault tolerance.
* **Security Groups**: Apply rule-based traffic filtering at the instance level to define what traffic is allowed in and out of your resources.
* **Reserved IP addresses**: Reserve an IP address specifically for you and attach and detach it with your VMs.

These services provide the foundation for secure, multi-tier network architectures, enabling you to replicate familiar AWS-like VPC patterns.

***

#### 🔧 Key Use Cases This Unlocks

* **Web & App Hosting**: Deploy multi-tier apps with frontend VMs, backend databases, isolated via Security Groups.
* **High-Performance Databases**: Run data-intensive workloads with IOPS-optimized block storage.
* **Enterprise Workloads**: Build full-stack production environments with persistent storage, private networks, and secure access controls.

***

#### 📢 Coming Soon

Stay tuned — we’re actively working on:

* Auto-scaling groups
* Load balancers
* Certificate Manager
* Object archival storage
* Private container registries and Kubernetes clusters

<br>




---

[Next Page](/llms-full.txt/1)

