<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Kirill Netreba on Medium]]></title>
        <description><![CDATA[Stories by Kirill Netreba on Medium]]></description>
        <link>https://medium.com/@kirill.netreba?source=rss-af7bd99f5c19------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*iRxn_r-qItfj9o54YdI6DA.png</url>
            <title>Stories by Kirill Netreba on Medium</title>
            <link>https://medium.com/@kirill.netreba?source=rss-af7bd99f5c19------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 23 May 2026 16:24:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kirill.netreba/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[SLA, SLO, and SLI — Key Service Reliability Metrics]]></title>
            <link>https://medium.com/@kirill.netreba/sla-slo-and-sli-key-service-reliability-metrics-d77dda4f9ccf?source=rss-af7bd99f5c19------2</link>
            <guid isPermaLink="false">https://medium.com/p/d77dda4f9ccf</guid>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[service-reliability]]></category>
            <category><![CDATA[reliability]]></category>
            <category><![CDATA[slo]]></category>
            <category><![CDATA[sla]]></category>
            <dc:creator><![CDATA[Kirill Netreba]]></dc:creator>
            <pubDate>Sat, 08 Mar 2025 11:50:39 GMT</pubDate>
            <atom:updated>2025-03-08T11:50:39.326Z</atom:updated>
            <content:encoded><![CDATA[<h3>SLA, SLO, and SLI — Key Service Reliability Metrics</h3><p><strong>SLA (Service Level Agreement)</strong> is a formal agreement between a service provider and client that defines the expected level of service. SLAs typically include service availability commitments and consequences for failing to meet them.</p><p><strong>SLO (Service Level Objective)</strong> represents specific reliability targets that a team aims to achieve. For example, 99.9% availability means the service can be down for no more than 43.8 minutes per month.</p><p><strong>SLI (Service Level Indicator)</strong> refers to actual metrics measuring service performance. Examples include request success rate or response time. SLIs show how well the service meets its stated SLOs.</p><p>Relationship between these metrics:</p><ul><li>SLA — Legal document with commitments</li><li>SLO — Internal team goals (usually stricter than SLA)</li><li>SLI — Actual service performance metrics</li></ul><p>Examples:</p><p><strong>SLA Example:</strong> “The service will be available 99.5% of the time, measured monthly. Failure to meet this commitment results in service credits.”</p><p><strong>SLO Example:</strong> “Our internal target is 99.9% availability, with 99% of requests completing within 200ms.”</p><p><strong>SLI Example:</strong> “Last month’s metrics: 99.95% uptime, average response time 150ms, 99.8% of requests successful.”</p><p>Common SLO Targets:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/1*cIwpej4b3_0N8t1UbISfxg.png" /></figure><p>These metrics help teams:</p><ul><li>Set clear expectations with customers</li><li>Monitor service health</li><li>Make data-driven decisions about reliability improvements</li><li>Balance reliability investments with other priorities</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d77dda4f9ccf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[About public, private keys and certificates]]></title>
            <link>https://medium.com/@kirill.netreba/about-public-private-keys-and-certificates-8165405d8a5b?source=rss-af7bd99f5c19------2</link>
            <guid isPermaLink="false">https://medium.com/p/8165405d8a5b</guid>
            <category><![CDATA[openssl]]></category>
            <category><![CDATA[openssl-certificate]]></category>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[ssh-keys]]></category>
            <category><![CDATA[https]]></category>
            <dc:creator><![CDATA[Kirill Netreba]]></dc:creator>
            <pubDate>Mon, 27 Jan 2025 19:38:48 GMT</pubDate>
            <atom:updated>2025-01-27T19:38:48.682Z</atom:updated>
            <content:encoded><![CDATA[<p>In today’s interconnected world, we constantly need to exchange sensitive information over potentially insecure networks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JhH5X9iPlok4eiTnERAwqw.png" /></figure><p>Whether it’s accessing your bank account, sending confidential emails, or deploying code to production servers, we need a way to ensure that:</p><ul><li>Only intended recipients can read the message (privacy)</li><li>Messages haven’t been tampered with (integrity)</li><li>We can verify who sent the message (authenticity)</li></ul><p>Simply using random strings or UUIDs as secret keys for secure data exchange isn’t enough because:</p><ul><li>They can be intercepted and reused by attackers</li><li>They don’t provide a way to verify the sender’s identity</li><li>They don’t ensure message integrity</li></ul><h3>Key Terms</h3><ul><li><strong>Encryption:</strong> Process of converting readable data (plaintext) into scrambled form (ciphertext) using a key</li><li><strong>Decryption:</strong> Converting ciphertext back to plaintext using the corresponding key</li><li><strong>Signing:</strong> Creating a digital signature using your private key to prove you authored/approved something</li><li><strong>Verification:</strong> Checking a digital signature using the sender’s public key to confirm authenticity</li></ul><blockquote>Related reading: <a href="https://medium.com/@kirill.netreba/hashing-encoding-encryption-e64470656406?source=your_stories_page-------------------------------------">Hashing, Encoding, Encryption</a></blockquote><h3>Key Concepts</h3><ul><li><strong>Public Key:</strong> Shared openly, used for encryption and verification</li><li><strong>Private Key:</strong> Kept secret, used for decryption and signing</li><li><strong>Digital Certificate:</strong> Contains public key and identity information, signed by a trusted authority</li><li><strong>Certificate Authority (CA):</strong> Trusted entity that issues and signs digital certificates</li></ul><p>Can we use private key for encryption and verification? <br>an we use public key for decryption and signing?</p><p>No! The roles of public and private keys cannot be reversed. Here’s why:</p><ul><li><strong>Encryption and Verification:</strong> Only public keys can be used for these operations because they are designed to be shared and used by anyone</li><li><strong>Decryption and Signing:</strong> Only private keys can perform these operations because they must be kept secret and prove ownership/authority</li></ul><p>This asymmetric relationship is what makes public key cryptography secure. If private keys could be used for encryption, anyone with access to the encrypted data would know which private key was used, compromising its secrecy.</p><h3>Common use cases</h3><h4>1. SSH Authentication</h4><ul><li>GitHub: SSH keys for repository access and deployment</li><li>Server access: Secure remote login without passwords</li><li>GitLab runners: Automated CI/CD pipeline authentication</li></ul><p><em>How SSH Authentication Works</em></p><ol><li>User generates SSH key pair locally</li><li>Public key is uploaded to remote system (GitHub/server/GitLab)</li><li>When connecting, user’s client proves ownership of private key</li><li>Remote system verifies proof using stored public key</li></ol><p>What does “proves ownership” means?</p><p>The SSH authentication process using private key ownership works like this:</p><ol><li>The client initiates connection to the server</li><li>Server sends a random challenge (a unique random string)</li><li>Client signs this challenge using their private key</li><li>Server verifies the signature using the stored public key</li></ol><p>This process, called “challenge-response authentication”, proves the client has the private key without ever transmitting it. The server can be confident it’s talking to the legitimate user because only someone with the correct private key could produce a valid signature for the challenge.</p><h4>2. Kubernetes</h4><ul><li>TLS certificates for API server communication</li><li>Client certificates for user authentication</li><li>Service account tokens and certificates</li></ul><p><em>Kubernetes Authentication Flow</em></p><ol><li>Cluster admin generates certificates for components</li><li>Certificates are distributed to respective services</li><li>Components use certificates to establish secure connections</li><li>API server validates certificates during communication</li></ol><p>Why just not to use private/public keys in k8s authentication flow?</p><p>While private/public key pairs alone could technically work for authentication, Kubernetes uses certificates (which include public keys) for several important reasons:</p><ul><li><strong>Additional metadata:</strong> Certificates contain important information like user identity, roles, and expiration dates</li><li><strong>Built-in expiration:</strong> Certificates have validity periods, forcing regular key rotation</li><li><strong>Trust chain:</strong> Certificates can be signed by a trusted Certificate Authority, creating a verifiable chain of trust</li><li><strong>Standard format:</strong> X.509 certificates are widely supported and have standardized tools for management</li></ul><p>These features make certificates more suitable for enterprise environments where security, compliance, and manageability are crucial.</p><h4>3. Web Security</h4><ul><li>SSL/TLS certificates for HTTPS websites</li><li>Client certificates for mutual TLS authentication</li><li>Code signing certificates</li></ul><p><em>Web Security Flow</em></p><ol><li>Website owner obtains certificate from Certificate Authority</li><li>Certificate (containing public key) is installed on web server</li><li>Browsers verify certificate using built-in CA certificates</li><li>Secure HTTPS connection is established using certificate</li></ol><p>Let’s break down the Web Security Flow in more detail</p><p><strong>1. Certificate Acquisition</strong></p><p>Website owners obtain certificates from Certificate Authorities (CAs), which are trusted organizations that verify domain ownership and issue certificates. Popular CAs include:</p><ul><li>Let’s Encrypt (free, automated)</li><li>DigiCert, Sectigo (commercial, with extended validation)</li></ul><p>While you can create your own CA using OpenSSL (called a self-signed certificate), browsers won’t trust it by default. Self-signed certificates are typically used only in development or internal environments.</p><p><strong>2. Certificate Installation</strong></p><p>“Installing” a certificate involves:</p><ul><li>Copying certificate files (.crt/.key) to a secure location on the web server</li><li>Configuring the web server (nginx/Apache) to use these certificate files</li><li>Setting correct file permissions to protect private keys</li></ul><p><strong>3. Browser Trust Mechanism</strong></p><p>Browsers maintain a list of trusted root certificates:</p><ul><li>Operating systems and browsers come with pre-installed root certificates from major CAs</li><li>This list is regularly updated through OS/browser updates</li><li>When visiting a website, the browser verifies its certificate was issued by one of these trusted CAs</li></ul><p><strong>Revised Web Security Flow</strong></p><ol><li>Website owner proves domain ownership to a Certificate Authority (CA)</li><li>CA verifies identity and issues a signed certificate</li><li>Website owner configures web server with certificate files:</li></ol><ul><li>Secure storage of private key</li><li>Configuration of web server software</li></ul><p>4. When users visit the site:</p><ul><li>Browser receives server’s certificate</li><li>Verifies it against built-in trusted CA certificates</li><li>Establishes encrypted HTTPS connection if verification succeeds</li></ul><h3>Tools for Key Management</h3><h3>OpenSSL</h3><p>Most versatile tool for certificate operations:</p><pre># Generate a private key<br>openssl genrsa -out private.key 2048<br><br># Create a certificate signing request (CSR)<br>openssl req -new -key private.key -out request.csr<br><br># Generate a self-signed certificate<br>openssl x509 -req -days 365 -in request.csr -key private.key -out certificate.crt<br><br># View certificate contents<br>openssl x509 -in certificate.crt -text -noout</pre><p>Let’s break down the OpenSSL commands:</p><ul><li><strong>genrsa</strong>: Generates a new RSA private key with specified key length (2048 bits is the minimum recommended)</li><li><strong>req -new</strong>: Creates a certificate signing request (CSR) needed when requesting certificates from CAs</li><li><strong>x509 -req</strong>: Signs the CSR with your private key to generate a self-signed certificate valid for 365 days</li><li><strong>x509 -text</strong>: Displays certificate information in human-readable format</li></ul><p>When running openssl req command, you’ll be prompted to enter various certificate details like Country, State, Organization, etc. For testing purposes, you can leave these fields empty by pressing Enter.</p><h3>ssh-keygen</h3><p>Primary tool for SSH key generation:</p><pre># Generate SSH key pair<br>ssh-keygen -t rsa -b 4096 -C &quot;your_email@example.com&quot;<br><br># List generated SSH key files<br>ls -la ~/.ssh/<br><br># Display public key content<br>cat ~/.ssh/id_rsa.pub<br><br># View private key content (keep this secret!)<br>cat ~/.ssh/id_rsa</pre><p>Let’s break down the ssh-keygen flags:</p><ul><li><strong>-t rsa</strong>: Specifies the type of key to create. RSA is the most common algorithm, but you can also use others like ed25519, dsa, or ecdsa</li><li><strong>-b 4096</strong>: Sets the key length in bits. 4096 provides strong security (2048 is minimum recommended)</li><li><strong>-C &quot;comment&quot;</strong>: Adds a comment to the key, typically your email address. This helps identify the key’s purpose or owner</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8165405d8a5b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hashing, Encoding, Encryption]]></title>
            <link>https://medium.com/@kirill.netreba/hashing-encoding-encryption-e64470656406?source=rss-af7bd99f5c19------2</link>
            <guid isPermaLink="false">https://medium.com/p/e64470656406</guid>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[hashing]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[encoding]]></category>
            <category><![CDATA[data-security]]></category>
            <dc:creator><![CDATA[Kirill Netreba]]></dc:creator>
            <pubDate>Sat, 27 Jul 2024 13:52:52 GMT</pubDate>
            <atom:updated>2024-07-27T13:52:52.762Z</atom:updated>
            <content:encoded><![CDATA[<p>Many people get confused by the terms hashing, encoding and encryption. Get a quick and easy-to-understand guide with Python code samples.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-HmVRW3U_Ml_JfPr-inqSg.png" /></figure><h3>Hashing</h3><p>Hashing — the process of converting input data of any size into a unique fixed amount of bytes using a special algorithm.</p><p>Features:</p><ul><li>Collisions can occur, but the probability is usually very low.</li><li>Each unique input data set gives a unique hash value (except in rare cases of collisions).</li><li>Irreversible process, meaning the original data cannot be recovered from the hash.</li></ul><p>Hashing Algorithms:</p><ul><li>SHA256, MD5, SHA1</li></ul><p>In Python you can use hashlib library which supports SHA256, MD5, and SHA1 algorithms.</p><pre>import hashlib<br><br># Example data<br>data = &quot;Hello, World!&quot;<br><br># SHA256<br>sha256_hash = hashlib.sha256(data.encode()).hexdigest()<br>print(&quot;SHA256:&quot;, sha256_hash)<br><br># MD5<br>md5_hash = hashlib.md5(data.encode()).hexdigest()<br>print(&quot;MD5:&quot;, md5_hash)<br><br># SHA1<br>sha1_hash = hashlib.sha1(data.encode()).hexdigest()<br>print(&quot;SHA1:&quot;, sha1_hash)</pre><p>Output:</p><pre>SHA256: dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f<br>MD5: 65a8e27d8879283831b664bd8b7f0ad4<br>SHA1: 0a0a9f2a6772942557ab5355d76af442f8f65e01</pre><h3>Encoding</h3><p>Encoding — the process of converting data into another format using a set of rules (or “codes”) so that the data can be easily recovered.</p><p>Features:</p><ul><li>Collisions do not occur; each unique input data set will always be converted into a unique output string.</li><li>Reversible process, meaning the data can be easily decoded back into the original format after encoding.</li></ul><p>Encoding Algorithms:</p><ul><li>Base64</li></ul><p>In Python you can use base64 library which supports Base64 encoding and decoding.</p><pre>import base64<br><br># Example data<br>data = &quot;Hello, World!&quot;<br><br># Encode<br>encoded_data = base64.b64encode(data.encode())<br>print(&quot;Encoded:&quot;, encoded_data)<br><br># Decode<br>decoded_data = base64.b64decode(encoded_data).decode()<br>print(&quot;Decoded:&quot;, decoded_data)</pre><p>Output:</p><pre>Encoded: b&#39;SGVsbG8sIFdvcmxkIQ==&#39;<br>Decoded: Hello, World!</pre><h3>Encryption</h3><p><strong>Encryption</strong> — the process of converting data into another format to hide the original content and prevent unauthorized access.</p><p>Features:</p><ul><li>Each unique input data set will be converted into a unique output string after encryption.</li><li>Reversible process, but the data can only be recovered using the corresponding encryption key.</li></ul><p>Encryption Algorithms:</p><ul><li>AES, RSA, DES</li></ul><p>In Python you can use cryptography library, which supports AES, RSA and DES algorithms.</p><pre>from cryptography.fernet import Fernet<br><br># Generate key<br>key = Fernet.generate_key()<br>cipher_suite = Fernet(key)<br><br># Example data<br>data = &quot;Hello, World!&quot;<br><br># Encrypt<br>cipher_text = cipher_suite.encrypt(data.encode())<br>print(&quot;Encrypted:&quot;, cipher_text)<br><br># Decrypt<br>plain_text = cipher_suite.decrypt(cipher_text).decode()<br>print(&quot;Decrypted:&quot;, plain_text)</pre><p>Output:</p><pre>Encrypted: b&#39;gAAAAABmpPPbnoBhSJbCdunYl1nPRyDXuhgoG3aLiAPbU7ZjRbQEt0BQJM5bepsgraBz97VYnuZF-uh_Xn6wPQLJE_Vpz260CQ==&#39;<br>Decrypted: Hello, World!</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e64470656406" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[StreamingResponse and FileResponse in FastAPI]]></title>
            <link>https://medium.com/@kirill.netreba/streamingresponse-and-fileresponse-in-fastapi-0bff51aaf3c5?source=rss-af7bd99f5c19------2</link>
            <guid isPermaLink="false">https://medium.com/p/0bff51aaf3c5</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[fastapi]]></category>
            <dc:creator><![CDATA[Kirill Netreba]]></dc:creator>
            <pubDate>Sat, 27 Jul 2024 12:05:35 GMT</pubDate>
            <atom:updated>2024-07-27T12:05:35.846Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>StreamingResponse</strong> and <strong>FileResponse</strong> serve different purposes in FastAPI, and their usage depends on the specific scenario and requirements.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0lHw7DDn6sIjuChlk6XLgg.png" /></figure><ol><li><strong>FileResponse</strong>:</li></ol><ul><li><strong>Description</strong>: Designed for sending files that already exist on the disk.</li><li><strong>Usage</strong>: Convenient when you have a file that is already saved on the disk and you just want to send it to the client.</li><li><strong>Performance</strong>: In this case, the server does not need to load the entire file into memory. Instead, it reads the file from the disk and sends it to the client.</li><li><strong>Example</strong>:</li></ul><pre>return FileResponse(image_file, media_type=&quot;image/png&quot;, filename=image_file)</pre><p>2. <strong>StreamingResponse</strong>:</p><ul><li><strong>Description</strong>: Allows streaming data to the client.</li><li><strong>Usage</strong>: Suitable for scenarios where data is generated dynamically and/or can be large in size. Also useful for sending data that is not saved on the disk.</li><li><strong>Performance</strong>: Can be more efficient for transmitting large data as it allows sending data in chunks without loading the entire file into memory.</li><li><strong>Example</strong>:</li></ul><pre>return StreamingResponse(io.BytesIO(data.read()), media_type=&quot;image/png&quot;)</pre><p><strong>Behavior Differences</strong>:</p><ul><li><strong>FileResponse</strong> reads the file from the disk and sends it to the client. It is convenient when the file already exists and does not require additional processing.</li><li><strong>StreamingResponse</strong> allows real-time data transmission, useful for cases where data is generated on-the-fly or can be large.</li></ul><p><strong>Which is Better?</strong></p><ul><li><strong>FileResponse</strong> is better suited for already existing files on the disk. It saves memory and simplifies the code.</li><li><strong>StreamingResponse</strong> is better suited for dynamically generated data or large files that are impractical to load entirely into memory before sending.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0bff51aaf3c5" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>