<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sameer Kulkarni</title>
    <description>The latest articles on Forem by Sameer Kulkarni (@samkulkarni20).</description>
    <link>https://forem.com/samkulkarni20</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F603473%2F817ad4bc-feca-4cae-a6d4-e857a5261e65.jpeg</url>
      <title>Forem: Sameer Kulkarni</title>
      <link>https://forem.com/samkulkarni20</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/samkulkarni20"/>
    <language>en</language>
    <item>
      <title>What are Vector Databases? A Beginner's Guide</title>
      <dc:creator>Sameer Kulkarni</dc:creator>
      <pubDate>Fri, 12 Jul 2024 05:18:49 +0000</pubDate>
      <link>https://forem.com/samkulkarni20/what-are-vector-databases-a-beginners-guide-iid</link>
      <guid>https://forem.com/samkulkarni20/what-are-vector-databases-a-beginners-guide-iid</guid>
      <description>&lt;p&gt;Have you ever used AI tools like &lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; to chat with a robot or &lt;a href="https://stability.ai/" rel="noopener noreferrer"&gt;Stable Diffusion&lt;/a&gt; to generate unique images? Wondered how they work?  &lt;/p&gt;

&lt;p&gt;Familiar apps, like the contacts app you use, use structured data, i.e., name, phone number, email address, and a few more text and numeric fields. While AI apps deal with different kinds of data that are unstructured. Some examples of unstructured data are articles, chats, pictures, multimedia, etc. These are quite complex for computer programs to process and understand the context.  &lt;/p&gt;

&lt;p&gt;Applications like contact apps work very well with SQL-type databases since their requirements are fairly simple. However, when it comes to AI apps and tools that refer to different kinds of unstructured data, regular databases aren't made to handle it. This is where vector databases come in! They're a special kind of database that helps AI platforms store and process unstructured data easily. That is why many AI tools are switching to vector databases or using them from the beginning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5b2v40v27bczgjy2ibs.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo5b2v40v27bczgjy2ibs.jpeg" alt="SQL &amp;amp; No-SQL Databses vs Vector Databases" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vector databases are the backbone of any AI application. In this blog post, we'll understand what they are and how they are different from traditional SQL and No-SQL databases, along with understanding the benefits they bring to the table. Let’s get started 🚀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of data
&lt;/h2&gt;

&lt;p&gt;Before diving deeper into the vectors and vector databases, let's first understand the types of data and how they affect the type of database best suited for its storage and querying capabilities. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmhg5f4asx1uax51crmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmhg5f4asx1uax51crmc.png" alt="Structured and Unstructured Data" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;center&gt;&lt;a href="https://k21academy.com/microsoft-azure/dp-900/structured-data-vs-unstructured-data-vs-semi-structured-data/" rel="noopener noreferrer"&gt;(K21Academy)&lt;/a&gt;&lt;/center&gt;
&lt;h3&gt;
  
  
  Structured data
&lt;/h3&gt;

&lt;p&gt;Any data that has a predefined and fixed schema for it is called structured data. This data can be represented in a tabular format. SQL databases, spreadsheets, etc. are best suited for storing and interacting with this type of data.       &lt;/p&gt;

&lt;h3&gt;
  
  
  Semi-structured data
&lt;/h3&gt;

&lt;p&gt;Semi-structured data is data with a flexible schema. In other words, it is “self-describing” data such as JSON or XML files. These files contain data as well as structural details about themselves. This type of data is ever-evolving, as it lacks a fixed schema.&lt;/p&gt;

&lt;p&gt;Document stores, Key-Value stores, and Graph databases are some examples of suitable databases for storing and analyzing semi-structured data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unstructured data
&lt;/h3&gt;

&lt;p&gt;Unstructured data is any other data that is mostly in the form of natural language and/or in multimedia format. Some examples of this type of data would be news articles, social media discussions, images, audio-visuals, etc. This is the largest form in which the data exists today and is the most difficult data to comprehend for computer systems as well. For example, consider a simple sentence “Sam likes Football”. Depending on the context and the background of the person, “Football” can either mean &lt;a href="https://en.wikipedia.org/wiki/American_football" rel="noopener noreferrer"&gt;American Football&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Association_football" rel="noopener noreferrer"&gt;Soccer&lt;/a&gt;. Similarly, a single picture can be seen and interpreted in numerous ways depending on the person, their point of view as well as the required information being seeked out of it. This is called &lt;a href="https://www.merriam-webster.com/dictionary/latent" rel="noopener noreferrer"&gt;latent&lt;/a&gt; semantic meaning of the given data. &lt;/p&gt;

&lt;p&gt;The latent semantic meaning of the data can be extracted by evaluating it against a large number of attributes, such as words immediately preceding and following the text, context of the data, person’s background, grammar, etc., and converting it into n-dimensional numerical arrays, i.e., vector embeddings.  &lt;/p&gt;

&lt;p&gt;Vector databases excel at storing, indexing, and querying such data.   &lt;/p&gt;

&lt;p&gt;Below image represents how the same kind of data can be represented in three different types listed above.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2o1z2g89u4g7ggzbpky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2o1z2g89u4g7ggzbpky.png" alt="Same kind of data can be represented in three different types: Structured, Semi-structured &amp;amp; Unstructured" width="797" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What are vectors?
&lt;/h2&gt;

&lt;p&gt;Vector is a mathematical concept which indicates information in more than one dimension. Being able to represent data in multiple dimensions is the key that helps vectors in AI and machine learning (ML). Unstructured data contains latent semantic meaning in multiple attributes. Hence the semantic meaning for any given data point needs to be captured with respect to all the relevant attributes for the model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3visruqwrap800reaa1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3visruqwrap800reaa1.png" alt="Vector in 2D space" width="323" height="367"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;center&gt;&lt;a href="https://commons.wikimedia.org/wiki/File:Vector_in_2D_space.png" rel="noopener noreferrer"&gt;(Wikimedia)&lt;/a&gt;&lt;/center&gt;

&lt;p&gt;Below are some examples of unstructured data containing semantic meaning in multiple attributes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Text&lt;/strong&gt;: The text you read can contain semantic information in many ways, such as individual words, their relationships, part of speech, sentence structure, grammar rules, overall topic/theme, sentiment, etc. Depending on the purpose, multiple AI models can use the same text data to evaluate the latent semantic meaning and form different vector data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Images&lt;/strong&gt;: Pixel data in images can be used to describe the image in vector forms. Some of the features that the models can consider would be colors, tones, shapes, edges, brightness, identifying objects, location, arrangement, artistic style, etc. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Audio&lt;/strong&gt;: For audio data, sound waves can be converted to numerical representations and evaluated on a number of parameters such as volume, timbre, tempo, attack and decay, frequencies, harmonics, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Vector embeddings
&lt;/h2&gt;

&lt;p&gt;In simple terms, vector embeddings, a.k.a. embeddings are high-dimensional vectors generated by neural networks. A typical vector database stores many such embeddings.&lt;/p&gt;

&lt;p&gt;Vectors help us represent data in mathematical form since modern CPUs and GPUs are best suited for working with mathematical data. Though, just turning data into a mathematical form isn’t useful if it cannot represent the &lt;strong&gt;meaning&lt;/strong&gt; of the data it represents. For example, we can easily compare words in two sentences using computers, but that may not tell us whether they mean the same thing or if they are about the same topic. This is where vector embeddings and embedding models come into play. The embedding model takes a large amount of &lt;strong&gt;labeled data&lt;/strong&gt; and converts it into numerical representation in a high-dimensional space. Each dimension represents a specific attribute or feature of the data extracted from it. &lt;/p&gt;

&lt;p&gt;Here is an example of vector embeddings generated using word2vec, a well-known model used to generate word embeddings. As you can see, it converts given words into an array of floating point numbers. It does that by evaluating the words on a set number of parameters, since computers can easily understand and process numbers than the meaning of words themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word&lt;/strong&gt;: "king"&lt;br&gt;&lt;br&gt;
  &lt;strong&gt;Embedding&lt;/strong&gt;: &lt;a href="https://dev.toThis%20is%20a%20reduced%20dimensionality%20example,%20actual%20embeddings%20can%20have%20hundreds%20of%20dimensions"&gt;-0.25, 0.42, 0.18, ..., 0.71&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word&lt;/strong&gt;: "queen"&lt;br&gt;&lt;br&gt;
  &lt;strong&gt;Embedding&lt;/strong&gt;: [-0.31, 0.38, 0.24, ..., 0.68]  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word&lt;/strong&gt;: "computer"&lt;br&gt;&lt;br&gt;
  &lt;strong&gt;Embedding&lt;/strong&gt;: [0.17, -0.52, 0.89, ..., 0.34]  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Word2vec" rel="noopener noreferrer"&gt;Word2vec&lt;/a&gt; is a classic example of a text embedding model for Natural Language Processing (NLP) algorithms. This model encodes semantic meaning and relationships between words. Thus, it is able to represent words with similar meanings closer together. The below image shows the visualization produced by TensorFlow’s projector tool for this model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0lzn0hjaqc7bz1r4ove.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0lzn0hjaqc7bz1r4ove.png" alt="Word2vec 10k embedding projector" width="649" height="481"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;center&gt;&lt;a href="https://projector.tensorflow.org/" rel="noopener noreferrer"&gt;(Word2vec 10k embedding projector)&lt;/a&gt;&lt;/center&gt;
&lt;h2&gt;
  
  
  How do vector databases work?
&lt;/h2&gt;

&lt;p&gt;Vector databases help store the vector embeddings generated by the embedding model. These vector embeddings are multidimensional numerical arrays that can sometimes span across hundreds of dimensions. Traditional scalar based databases can’t work with this type of data efficiently; this is why we need specialized databases like vector databases which are specifically designed to handle this data type. Some reasons why traditional databases can’t work with vector data efficiently are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vector embeddings that are high-dimensional arrays of numbers don’t fit neatly into a structured format.&lt;/li&gt;
&lt;li&gt;The indexing algorithms of traditional databases are optimized for structured and semi-structured data. Vector embeddings need a different set of algorithms for indexing.&lt;/li&gt;
&lt;li&gt;Traditional databases lack the functionality to perform complex distance calculations, like cosine similarity, needed to compare and query vectors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below diagram shows a simplified way a typical vector database works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8sb7p19gjb52bdqnwn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8sb7p19gjb52bdqnwn6.png" alt="How do vector databases work" width="645" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we feed the embedding model with the required labeled data in large quantities. The embedding model consists of execution of a data pipeline that largely consists of two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preprocessing&lt;/strong&gt;: During preprocessing, the model cleans the data, removes noise, and inconsistencies, and then normalizes the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Embedding&lt;/strong&gt;: The embedding stage includes feature extraction &amp;amp; vectorization (encoding) of the data followed by dimensionality reduction. The last step reduces the number of dimensions of the vector, if needed, for efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The vector embeddings are then inserted into the vector database for long term storage. The embeddings also contain some reference to the original content it was created from. Once enough vector data has been inserted into the database, the data that has similar semantic meaning naturally gravitates closer together.  &lt;/p&gt;

&lt;p&gt;In order to get query results from the database, the query is also run through the same embedding model as the data. This converts the query into another vector. The vector database then searches for data points closest to the query vector based on the distance metric and returns the results. In some cases, the database also needs to post-process the nearest neighbors of the queried data before returning them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Indexing algorithms
&lt;/h2&gt;

&lt;p&gt;The AI and ML applications need to be trained on a large amount of data. In addition to that, the fact that the vector embeddings generated can have hundreds of dimensions means that the vector databases need to store a huge amount of data. Querying over such a huge amount of data is quite cumbersome, even for vector databases. Hence, similar to scalar based databases, indexing also helps vector databases with faster query retrievals. The vector db indexes create a quickly traversable data structure using several algorithms. Below are some of the common ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hierarchical Navigable Small World (HNSW)
&lt;/h3&gt;

&lt;p&gt;HNSW builds a hierarchical structure. Each node in the hierarchy represents a set of vectors, and each edge represents the similarity between the vectors. It organizes the data points into a series of graphs at different levels, and similar data points are connected within each graph.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fauly7yhicnty3tv0jagc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fauly7yhicnty3tv0jagc.png" alt="Hierarchical Navigable Small World" width="535" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The benefits of HNSW include efficient approximate nearest neighbor searches, fast search times, and scalability with large datasets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Locality Sensitive Hashing (LSH)
&lt;/h3&gt;

&lt;p&gt;Locality sensitive hashing projects data points onto multiple hash tables using hash functions. These hash functions map similar vectors to the same or similar bucket which helps the database locating the query results faster.  &lt;/p&gt;

&lt;p&gt;The benefits of using LSH for indexing are very fast filtering of dissimilar points and being especially useful for large datasets with high dimensionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product Quantization (PQ)
&lt;/h3&gt;

&lt;p&gt;Product quantization is a lossy compression technique for high dimensional data. It reduces the dimensionality of the vectors into subvectors using codebooks and quantizes each subvector separately. During encoding, the original vector is compared to the codewords in the codebook, and the closest ones are selected to represent the original vector.&lt;/p&gt;

&lt;p&gt;PQ helps in efficient approximate nearest neighbor search and reduction in storage requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases of Vector databases
&lt;/h2&gt;

&lt;p&gt;Vector databases are a useful tool in many applications. Here are some use cases of the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommendation systems
&lt;/h3&gt;

&lt;p&gt;Recommending articles, movies, music, products, etc., based on user preferences and/or the given description in text or other formats. They can store user profiles and item embeddings for efficient retrieval of similar items to recommend. This can help social media platforms, media publishing houses, and OTT platforms engage users and build brand loyalty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Natural language processing (NLP)
&lt;/h3&gt;

&lt;p&gt;Vector databases make tasks like sentiment analysis, topic modeling, and machine translation possible and efficient. They can store word as well as sentence embeddings enabling fast processing of large natural language data. This helps search engines provide better results, as well as chatbots and virtual assistants.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fraud detection and anomaly detection
&lt;/h3&gt;

&lt;p&gt;Vector databases help in analyzing and detecting unusual patterns, objects, behaviors in various data forms. They can store historical transaction embeddings or sensor data embeddings, which allows real-time detection of suspicious patterns. It is used by financial organizations to prevent financial frauds in their tracks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Drug discovery and material science
&lt;/h3&gt;

&lt;p&gt;Finding similarity to existing data is an important capability for identifying potential drug candidates or new alternatives to existing materials. Vector databases can store molecular embeddings or material property embeddings, enabling faster scientific discoveries. This helps to significantly reduce the time it takes to develop new drugs and discover newer materials for specific applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vector DB classification
&lt;/h2&gt;

&lt;p&gt;The vector databases are broadly classified using two aspects.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dedicated vector database&lt;/li&gt;
&lt;li&gt;Licensing model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dedicated vector databases have certain advantages over traditional databases that support vector search. They are built for speed, with optimized indexing and scalability. On the other hand, traditional databases with support for vector search have advantages like the ability to handle structured and/or unstructured data along with vectors, with a smoother learning curve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57vao9zg9xgcf2p94kuo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57vao9zg9xgcf2p94kuo.png" alt="Vector databases landscape" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;center&gt;&lt;a href="https://blog.det.life/why-you-shouldnt-invest-in-vector-databases-c0cd3f59d23c" rel="noopener noreferrer"&gt;(Vector databases landscape)&lt;/a&gt;&lt;/center&gt;

&lt;p&gt;The diagram above shows a few of the popular vector database options available today and how they fit into the landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Vector databases are revolutionizing how we handle and interact with large and complex data in the age of artificial intelligence. They unlock a vast range of possibilities through their ability to capture, persist and efficiently search through the essence of data. From powering recommendation systems to accelerating scientific discovery, vector databases are bound to play a central role in the upcoming data driven future. &lt;/p&gt;

&lt;p&gt;As new vector databases emerge and evolve, we can expect even faster speeds, larger storage capacities, more sophisticated indexing and world-wide adoption of them across industries. &lt;/p&gt;

&lt;p&gt;Now that you have learned about vector databases, how they work, their use cases, and classification, you can bring in &lt;a href="https://www.infracloud.io/build-ai-cloud/" rel="noopener noreferrer"&gt;AI &amp;amp; GPU Cloud experts&lt;/a&gt; to help you build your own AI cloud. &lt;/p&gt;

&lt;p&gt;If you found this post useful and informative, subscribe to our weekly newsletter for more posts like this. Do start a conversation about this post on &lt;a href="https://www.linkedin.com/in/sameer-kulkarni-9875773b/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. I’d love to hear your thoughts.&lt;/p&gt;

</description>
      <category>vectordatabase</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>database</category>
    </item>
    <item>
      <title>Securing Kubernetes Secrets with Conjur</title>
      <dc:creator>Sameer Kulkarni</dc:creator>
      <pubDate>Fri, 26 Mar 2021 17:58:02 +0000</pubDate>
      <link>https://forem.com/samkulkarni20/securing-kubernetes-secrets-with-conjur-35hk</link>
      <guid>https://forem.com/samkulkarni20/securing-kubernetes-secrets-with-conjur-35hk</guid>
      <description>&lt;h3&gt;
  
  
  Why to secure Kubernetes secrets?
&lt;/h3&gt;

&lt;p&gt;Secrets management is one of the important aspects of securing your Kubernetes cluster. Out of the box, Kubernetes uses base 64 encoding for storing them, which is not enough. You have to implement a number of security best practices on top, to prevent possible security breaches. etcd encryption at rest, access control with RBAC, are a couple of examples of the same. Using secrets management solutions like CyberArk Conjur, not only secures them for Kubernetes, but also provides other benefits as we will see in the post.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Conjur?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.conjur.org/"&gt;CyberArk Conjur&lt;/a&gt; is a secrets manager. It helps you manage secrets in Kubernetes, as well as across applications, tools &amp;amp; clouds. It offers Role Based Access Control (RBAC) with an audit trail to easily track each stored secret. It implements encryption at rest with AES-256-GCM and in transit using mTLS. Additionally, you can manage the access for each secret &amp;amp; can also rotate the secrets automatically.&lt;/p&gt;

&lt;p&gt;In this post, we will see how to install Conjur OSS on Kubernetes. We will go through a basic set of Conjur policies and will load them into Conjur. We’ll also see how to run an application in Kubernetes which uses secrets from Conjur by conforming to the defined policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Familiarity with advanced YAML concepts.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may be already familiar with the way Kubernetes spec files are written in YAML. Although you also need to understand a few more YAML concepts to understand &amp;amp; define Conjur policies, viz. &lt;strong&gt;tags, anchors &amp;amp; aliases&lt;/strong&gt;. Conjur website has a &lt;a href="https://docs.conjur.org/Latest/en/Content/Operations/Policy/policy-syntax.htm"&gt;quick refresher&lt;/a&gt; on this. Alternatively, you can go through the &lt;a href="https://yaml.org/spec"&gt;full YAML documentation&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A working Kubernetes cluster&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker installed locally&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to Install Conjur?
&lt;/h3&gt;

&lt;p&gt;The easiest way to Install Conjur on a Kubernetes cluster is by using the Helm chart. Let's first create a custom values file for the Helm chart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$  DATA_KEY="$(docker run --rm cyberark/conjur data-key generate)"
$  HELM_RELEASE_NAME=conjur-oss
$  cat &amp;gt;values.yaml &amp;lt;&amp;lt;EOT
account:
  name: "default"
  create: true
authenticators: "authn-k8s/namespace,authn-k8s/deployment,authn-k8s/service_account,authn-k8s/demo,authn"
dataKey: $DATA_KEY
ssl:
  altNames:
  - $HELM_RELEASE_NAME
  - $HELM_RELEASE_NAME-ingress
  - $HELM_RELEASE_NAME.conjur.svc.cluster.local
  - $HELM_RELEASE_NAME-ingress.conjur.svc.cluster.local
service:
  external:
    enabled: false
replicaCount: 1
EOT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;dataKey&lt;/code&gt; is used for encrypting the secrets in the db. The &lt;code&gt;ssl.altNames&lt;/code&gt; will be used for the SSL configuration of the Conjur service that the Helm chart will create. &lt;/p&gt;

&lt;p&gt;Install Conjur OSS on a Kubernetes cluster, with the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$  CONJUR_NAMESPACE=conjur
$  kubectl create namespace "$CONJUR_NAMESPACE"
$  VERSION=2.0.3
$  helm repo update
$  helm install \
   -n "$CONJUR_NAMESPACE" \
   -f values.yaml \
   "$HELM_RELEASE_NAME" \
   https://github.com/cyberark/conjur-oss-helm-chart/releases/download/v$VERSION/conjur-oss-$VERSION.tgz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;VERSION&lt;/code&gt; declared above is the Conjur Helm chart release version. As of writing this post, the latest Conjur OSS Helm chart version is &lt;code&gt;2.0.3&lt;/code&gt;. Refer &lt;a href="https://github.com/cyberark/conjur-oss-helm-chart/releases"&gt;Conjur Helm chart releases&lt;/a&gt; for the latest Conjur Helm chart available.&lt;/p&gt;

&lt;p&gt;Once the helm chart is installed, it creates an admin user. You will need this key for the initial load of the Conjur policies, secrets, etc. You'll also need it in the "break-glass" scenarios. Hence you need to store it in a safe place. You can fetch the same using the commands below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ POD_NAME=$(kubectl get pods --namespace $CONJUR_NAMESPACE \
                     -l "app=$HELM_RELEASE_NAME,release=$HELM_RELEASE_NAME" \
                     -o jsonpath="{.items[0].metadata.name}")
$ kubectl exec --namespace $CONJUR_NAMESPACE \
          $POD_NAME \
          --container=$HELM_RELEASE_NAME \
          -- conjurctl role retrieve-key default:user:admin | tail -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get po,svc -n $CONJUR_NAMESPACE
NAME                             READY   STATUS    RESTARTS   AGE
pod/conjur-oss-b888db5d5-vmfl5   1/2     Running   0          77s
pod/conjur-oss-postgres-0        1/1     Running   0          77s

NAME                          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
service/conjur-oss            NodePort    10.68.34.148   &amp;lt;none&amp;gt;        443:31022/TCP   79s
service/conjur-oss-postgres   ClusterIP   10.68.36.72    &amp;lt;none&amp;gt;        5432/TCP        79s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Define Conjur Policies
&lt;/h3&gt;

&lt;p&gt;Conjur policies help define objects in its database in a tree structure. Some examples of the objects defined in the policies are users, roles, secrets &amp;amp; applications. It also defines rules the for role based access control. While the Conjur documentation defines the &lt;a href="https://docs.conjur.org/Latest/en/Content/Operations/Policy/policy-best-practices.htm?TocPath=Fundamentals%7CPolicy%20Management%7C_____5"&gt;policy best practices&lt;/a&gt;, we will use one of the &lt;a href="https://github.com/conjurdemos/kubernetes-conjur-demo"&gt;Conjur demo repositories&lt;/a&gt; to define policies. I've used policies in the demo repository as the base and have further simplified them to understand the basic concepts better. Download and review the &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/tree/main/policy"&gt;simplified policy files from my repository&lt;/a&gt;. Note that all the policies need to have a &lt;code&gt;.yml&lt;/code&gt; extension.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1_users.yml&lt;/code&gt; file defines users and roles. It also grants role based access to a group of users as well as to individual users.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2_app_authn-def.yml&lt;/code&gt; file defines applications &amp;amp; groups them into a layer for easier access management.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3_cluster-authn-svc-def.yml&lt;/code&gt; file defines the authenticator service &amp;amp; the SSL certificates for the mTLS communication between Conjur &amp;amp; its clients. In this case, Conjur clients are applications running on Kubernetes. It also defines role based access to authenticate with the service.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4_app-identity-def.yml&lt;/code&gt; file connects the authentication identities to application identities.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;5_authn-any-policy-branch.yml&lt;/code&gt; policy is defined to verify that hosts can authenticate with Conjur from anywhere in the policy branch to retrieve secrets for Kubernetes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;6_app-access.yml&lt;/code&gt; defines secret variables for different applications that will use Conjur as its secrets manager. Note that the variables mentioned here are just secret variable names &amp;amp; not the values.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generate mTLS cert &amp;amp; key
&lt;/h3&gt;

&lt;p&gt;Run the &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/blob/main/create_mtls_certs.sh"&gt;create_mtls_certs.sh&lt;/a&gt; shell script to create the mTLS cert &amp;amp; key. Make sure to update the &lt;code&gt;AUTHENTICATOR_ID&lt;/code&gt; &amp;amp; &lt;code&gt;CONJUR_ACCOUNT&lt;/code&gt; in the script with the values appropriate for the Conjur installation. &lt;code&gt;AUTHENTICATOR_ID&lt;/code&gt; is the part that follows &lt;code&gt;conjur/authn-k8s/&lt;/code&gt; in the &lt;code&gt;id&lt;/code&gt; of the &lt;code&gt;3_cluster-authn-svc-def.yml&lt;/code&gt; policy file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load policies &amp;amp; secrets
&lt;/h3&gt;

&lt;p&gt;We'll use &lt;code&gt;conjur-cli&lt;/code&gt; to load policies &amp;amp; data in Conjur. Conjur has a container image pre-packaged with the Conjur cli. We will run the Conjur client as a pod on the cluster. The policies and certificates will get mounted on the same as configmap volumes. &lt;code&gt;conjur-cli&lt;/code&gt; will load the policies &amp;amp; certificates to the Conjur server from these volumes. &lt;/p&gt;

&lt;p&gt;Have all the policy files under the &lt;code&gt;policy&lt;/code&gt; directory and the mTLS cert-key pair in &lt;code&gt;mtls&lt;/code&gt; directory to create configmaps out of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ # Create configmap containing the mTLS cert &amp;amp; key
$ kubectl create configmap conjur-ca -n $CONJUR_NAMESPACE --from-file $(pwd)/mtls
$ # Create a configmap containing all the policy files
$ kubectl create configmap policies -n $CONJUR_NAMESPACE --from-file $(pwd)/policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the Conjur client pod with the above configmaps mounted as volumes. Download the sample pod config from &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/blob/main/deploy/conjur-client.yaml"&gt;here&lt;/a&gt;. Create the pod with downloaded config &amp;amp; exec into it to load values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create -f conjur-client.yaml
$ kubectl exec -it -n $CONJUR_NAMESPACE conjur-client -- sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect to the Conjur server &amp;amp; authenticate as an admin user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ export CONJUR_URL=https://conjur-oss
$ export ACCOUNT=default
$ conjur init -u $CONJUR_URL -a $ACCOUNT
$ conjur authn login -u admin -p &amp;lt;admin_api_key_printed_by_helm_install&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can start loading policies now. Loading the policy files &lt;code&gt;1_users.yml&lt;/code&gt; and &lt;code&gt;2_app-authn-def.yml&lt;/code&gt; in Conjur generates API keys for the users &amp;amp; hosts defined in it. The user API keys can be distributed to respective team members, allowing them to authenticate &amp;amp; interact with Conjur. We will use the &lt;a href="https://docs.conjur.org/Latest/en/Content/Operations/Services/k8s_auth.htm"&gt;Kubernetes authenticator&lt;/a&gt; instead of host API keys to get the application authenticated with Conjur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ conjur policy load root policy/1_users.yml
$ conjur policy load root policy/2_app-authn-def.yml
$ conjur policy load root policy/3_cluster-authn-svc-def.yml
$ conjur policy load root policy/4_app-identity-def.yml
$ conjur policy load root policy/5_authn-any-policy-branch.yml
$ conjur policy load root policy/6_app-access.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load mTLS certificate &amp;amp; key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ conjur variable values add conjur/authn-k8s/demo/ca/cert "$(cat conjur-ca/ca.cert)"
$ conjur variable values add conjur/authn-k8s/demo/ca/key "$(cat conjur-ca/ca.key)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load secret values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ conjur variable values add demo-app-vars/url "https://my.app.com"
$ conjur variable values add demo-app-vars/username "myuser"
$ conjur variable values add demo-app-vars/password "supersecret"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don’t want the client pod to continue running in the cluster, especially because it’s currently logged in to the Conjur server. Hence either log out from the Conjur server with &lt;code&gt;conjur authn logout&lt;/code&gt; or delete the &lt;code&gt;conjur-client&lt;/code&gt; pod. Also, delete the configmaps mounted on the client pod.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete -f conjur-client.yaml
$ kubectl delete cm conjur-ca policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure &amp;amp; run application
&lt;/h3&gt;

&lt;p&gt;Conjur offers various &lt;a href="https://docs.conjur.org/Latest/en/Content/Operations/Services/Authentication-new.htm?tocpath=Fundamentals%7CAuthentication%7C_____0"&gt;authenticators&lt;/a&gt; for users and hosts. Here we will use the &lt;a href="https://docs.conjur.org/Latest/en/Content/Operations/Services/k8s_auth.htm?tocpath=Fundamentals%7CAuthentication%7C_____8"&gt;Kubernetes authenticator&lt;/a&gt; to get our application host authenticated with the Conjur server. Kubernetes authenticator uses Kubernetes APIs to authenticate resources like Pod, Deployment, etc. Refer &lt;a href="https://docs.conjur.org/Latest/en/Content/Integrations/Kubernetes_AppIdentity.htm?tocpath=Integrations%7COpenShift%252C%20Kubernetes%7C_____2#SupportedKubernetesresources"&gt;Conjur documentation&lt;/a&gt; to see the full list of supported Kubernetes resources that can be defined as hosts. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.conjur.org/Latest/en/Content/Integrations/Kubernetes_deployAuthenticatorSidecar.htm"&gt;Kubernetes Authenticator Client&lt;/a&gt; is one of the two options for using this authentication method. You can run it as &lt;code&gt;initContainer&lt;/code&gt; or as &lt;code&gt;sidecar&lt;/code&gt; for each application. Configure the Conjur url, account, login, etc as the env variables on the application and the authenticator container. Login is the full host id as defined in the &lt;code&gt;2_app-authn-def.yml&lt;/code&gt; policy file. You also need to mount the SSL certs for the Conjur service. In this case, we have to use the SSL certificates generated by Helm chart during Conjur installation. If you have your own SSL certificates configured on the Conjur server, you can use the same. Note that the value of &lt;code&gt;CONJUR_AUTHN_URL&lt;/code&gt; on the authenticator container is slightly different from the &lt;code&gt;CONJUR_APPLIANCE_URL&lt;/code&gt; on the application container. &lt;code&gt;CONJUR_AUTHN_URL&lt;/code&gt; has the authetication service id appended to the &lt;code&gt;CONJUR_APPLIANCE_URL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Authentication client authenticates itself to the configured Conjur server url &amp;amp; provides it's identity, i.e., the login id, pod name, namespace, etc. Conjur validates the information provided by the authenticator client against defined policies, as well as, Kubernetes &amp;amp; provides an access token. The access token is valid only for 8 mins. Client container saves the authentication token on an in-memory volume, which is mounted to both the containers viz. application &amp;amp; authenticator. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.conjur.org/Latest/en/Content/Tools/summon.html?tocpath=Developer%7C_____1"&gt;Summon&lt;/a&gt; which is a separate open source utility from CyberArk Conjur, uses this token to fetch the values for secrets. Your application container needs to run &lt;code&gt;Summon&lt;/code&gt; as its main process with path to a &lt;code&gt;secrets.yml&lt;/code&gt; file that lists all the secret values that it needs to pull from Conjur. Summon runs the application executable as a sub-process &amp;amp; passes the secret values it fetched as env variables. See the command configured on the &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/blob/main/Dockerfile"&gt;Dockerfile&lt;/a&gt; of the application we're about to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tail -n1 Dockerfile
ENTRYPOINT ["summon", "--provider", "summon-conjur", "-f", "/etc/secrets.yml", "/bin/sh", "-c", "while true; do printenv | grep PASSWORD; sleep 5; done"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;!var&lt;/code&gt; in the &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/blob/main/secrets.yml"&gt;secrets.yml&lt;/a&gt; file indicates that the value needs to be injected as env variable. It can be replaced with &lt;code&gt;!file:var&lt;/code&gt; in case you want the value to be written to a file. In that case, the env variable name on the left side will contain the file's path where secret content is written. Observe the contents of our &lt;code&gt;secrets.yml&lt;/code&gt; below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat secrets.yml
PASSWORD: !var demo-app-vars/password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before running the application, let's first create our application namespace &amp;amp; copy the secret containing Conjur tls certs to our application namespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create namespace test
$ kubectl get secret conjur-oss-conjur-ssl-cert --namespace=conjur -oyaml |\
 sed 's/namespace: conjur/namespace: test/g' |\
 kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the example &lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration/blob/main/deploy/busybox.yaml"&gt;application deployment file&lt;/a&gt; to run the application. As you saw in the &lt;code&gt;Dockerfile&lt;/code&gt;, my example application is a busybox container. It just prints the value of secret &lt;code&gt;demo-app-vars/password&lt;/code&gt; from Conjur every 5 seconds. A typical application should never print secret values in logs; but we'll use it only to demonstrate that the value is available to the application from Conjur. Let's run the same &amp;amp; observe the logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl create -f busybox.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check to see if the application has the secret value from Conjur available as an environment variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl logs -f -lapp=busybox
pass: supersecret
pass: supersecret
pass: supersecret
pass: supersecret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An additional security feature you get by using Conjur &amp;amp; Summon is that the secret value is only available to the application &amp;amp; not to the entire container. This means, if an attacker were to get access inside the application container, they won't be able to access the secret values by listing the environment variables in the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl exec -it -lapp=busybox -- sh
$ printenv | grep PASSWORD
$
$ # No output above
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cleanup
&lt;/h3&gt;

&lt;p&gt;Cleanup all the resources created in this post with the below commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete -f busybox.yaml
$ helm delete $HELM_RELEASE_NAME -n $CONJUR_NAMESPACE
$ 
$ ## Delete client pod &amp;amp; configmap, if not already removed
$ kubectl delete -f conjur-client.yaml
$ kubectl delete cm -n $CONJUR_NAMESPACE conjur-ca policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we looked at what Conjur is, its uses &amp;amp; basic concepts. We also installed Conjur on a Kubernetes cluster and integrated it with a sample application running in Kubernetes. Hope this gives you a good start for using Conjur with Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We’re always thrilled to connect to people working with cloud native technologies. For any queries or comments, you can reach out to us via &lt;a href="https://twitter.com/infracloudio"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.linkedin.com/company/infracloudio"&gt;LinkedIn&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://conjur.org"&gt;conjur.org&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/cyberark/conjur-oss-helm-chart/tree/master/conjur-oss"&gt;Conjur OSS Helm Chart&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/conjurdemos/kubernetes-conjur-demo"&gt;Kubernetes Conjur Demo&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/samkulkarni20/conjur-k8s-integration"&gt;My GitHub repo with all the resources used in the post&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>security</category>
      <category>conjur</category>
      <category>cloudnative</category>
    </item>
  </channel>
</rss>
