{"id":1748,"date":"2025-10-10T12:34:22","date_gmt":"2025-10-10T11:34:22","guid":{"rendered":"https:\/\/editjournal.redakt.eu\/faxmodem\/?p=1748"},"modified":"2025-10-10T14:15:06","modified_gmt":"2025-10-10T13:15:06","slug":"certbot-dns-oci-api-credentials-ini","status":"publish","type":"post","link":"https:\/\/editjournal.redakt.eu\/faxmodem\/blog\/development\/cloud-serverless\/certbot-dns-oci-api-credentials-ini\/","title":{"rendered":"Creating API credentials for certbot-dns-oci"},"content":{"rendered":"<h2>The setup<\/h2>\n<p>You want to generate Letsencrypt certificates using <a href=\"https:\/\/letsencrypt.org\/docs\/challenge-types\/#dns-01-challenge\"><code>DNS-01<\/code> challenge<\/a> (e.g. wildcard certificates) and you host your domain on Oracle Cloud. Your code is in Python and you want to use <a href=\"https:\/\/pypi.org\/project\/certbot-dns-oci\/\">certbot-dns-oci<\/a> for updating the TXT DNS records for the <code>DNS-01<\/code> challenge.<\/p>\n<h2>The problem<\/h2>\n<p>You need to provide some OCI credentials to <code>certbot-dns-oci<\/code> and it's not obvious where and how do you get them.<\/p>\n<p>Here's what <code>certbot-dns-oci<\/code> says:<\/p>\n<blockquote>\n<p><strong>--dns-oci-credentials<\/strong> has special value <code>instance_principal<\/code> that switches<br \/>\ncertbot to use the instance principal for OCI authentication<br \/>\n(<a href=\"https:\/\/docs.oracle.com\/en-us\/iaas\/Content\/Identity\/Tasks\/callingservicesfrominstances.htm\">please, read the documentation about the feature.<\/a>)<br \/>\nCorresponding dynamic group must be able to read <code>dns-zones<\/code> in compartment<br \/>\nand manage <code>dns-records<\/code>.<\/p>\n<p>In other cases, plugin requires the<br \/>\n<a href=\"https:\/\/docs.oracle.com\/en-us\/iaas\/Content\/API\/Concepts\/sdkconfig.htm\">OCI credentials configuration file<\/a>,<br \/>\nwhich is <code>~\/.oci\/config<\/code> by default.<br \/>\nThe profile can be specified by <strong>--dns-oci-profile<\/strong> (usually <code>DEFAULT<\/code>).<\/p>\n<\/blockquote>\n<h2>The credentials<\/h2>\n<h3>1. Create user, group and policy<\/h3>\n<ol>\n<li>Go to OCI console \u2192 <em>Identity &amp; Security<\/em> \u2192 <em>Domains<\/em><br \/>\nDomains here means Identity Domains. Every tenancy has at least one, usually named \u201cDefault\u201d.<\/li>\n<li>Open the domain and click the <em>User management<\/em> tab<\/li>\n<li>Under <em>Groups<\/em> click <em>Create<\/em>. Name the group e.g. <em>DNS Managers<\/em> (can be any name you want). Once created, copy the group OCID to use in step 4<\/li>\n<li>Under <em>Users<\/em> click <em>Create<\/em>. Uncheck <em>Use email as username<\/em>. Provide username and last name (can be the same). Assign user to the <em>DNS Managers<\/em> group<\/li>\n<li>\n<p>Go to OCI console \u2192 <em>Identity &amp; Security<\/em> \u2192 <em>Policies<\/em>. Create new policy with statement:<\/p>\n<pre><code>Allow group id OCID to manage dns in tenancy<\/code><\/pre>\n<p>Use the <code>OCID<\/code> for the group you created, e.g. <code>ocid1.group.oc1.abc...def<\/code>.<br \/>\nHere's <a href=\"https:\/\/docs.oracle.com\/en-us\/iaas\/Content\/Identity\/Concepts\/policysyntax.htm\">documentation on policy syntax<\/a>.<\/p>\n<\/li>\n<\/ol>\n<h3>2. Get API keys<\/h3>\n<ol>\n<li>Open the newly created user and click <em>API keys<\/em><\/li>\n<li>Click <em>Add API key<\/em><\/li>\n<li>Since <em>Generate API key pair<\/em> is selected by default, you can download the private and public keys right away<\/li>\n<li>Once the keys are downloaded, you can click <em>Add<\/em> to proceed<\/li>\n<\/ol>\n<h3>3. Create configuration file<\/h3>\n<p>You will get the <em>Configuration file preview<\/em> screen where it shows your key fingerprint and the template to create an <code>.ini<\/code> configuration file.<\/p>\n<p>The template will look like this:<\/p>\n<pre><code>[DEFAULT]\nuser=ocid1.user.oc1.abc...def\nfingerprint=ab:cd:...:ef\ntenancy=ocid1.tenancy.oc1.abc...def\nregion=&lt;your-region-here, e.g. `us-ashburn-1`&gt;\nkey_file=&lt;path to your private keyfile&gt; # TODO<\/code><\/pre>\n<p>Each key is documented in <a href=\"https:\/\/docs.oracle.com\/en-us\/iaas\/Content\/API\/Concepts\/sdkconfig.htm#File_Entries\">SDK and CLI Configuration File \u2192 File Entries<\/a>.<\/p>\n<h2>Test user<\/h2>\n<p>Use Cloud Shell right in OCI Console. You will have to upload the .pem and the .ini and then issue some dns command using these credentials to see if they work.<\/p>\n<p>On top right click Developer Tools \u2192 Cloud Shell. You get something that looks like SSH in your browser.<\/p>\n<pre><code>mkdir -p ~\/.oci\nvi ~\/.oci\/config<\/code><\/pre>\n<p>Paste your .ini contents into <code>~\/.oci\/config<\/code>. Gotchas:<\/p>\n<ul>\n<li>replace <code>[DEFAULT]<\/code> with username we're testing, e.g. <code>api_dns_user<\/code><\/li>\n<li>replace <code>key_file<\/code> with where the private key will actually be, e.g. <code>~\/.oci\/api_dns_user.pem<\/code><\/li>\n<li>ensure <code>chmod 600 ~\/.oci\/config<\/code> and <code>chmod 600 ~\/.oci\/api_dns_user.pem<\/code>, else it will complain permissions are too open<\/li>\n<\/ul>\n<p>Lastly, you will need your compartment OCID. You can get it in Cloud Shell:<\/p>\n<pre><code>oci iam compartment list --all --include-root --query &quot;data[?\\&quot;compartment-id\\&quot;==null].id | [0]&quot; --raw-output<\/code><\/pre>\n<p>Now we can test the credentials:<\/p>\n<pre><code>oci --auth api_key --config-file ~\/.oci\/config --profile api_dns_user dns zone list --compartment-id COMPARTMENT_OCID<\/code><\/pre>\n<h2>Bonus points<\/h2>\n<p>If you're automating deployment, you will need to store the private key only.<\/p>\n<p>The fingerprint can be easily derived by using:<\/p>\n<pre><code>openssl rsa -pubout -outform DER -in &quot;\/path\/to\/private-key.pem&quot; 2&gt;\/dev\/null | openssl md5 -c | awk &#039;{print $2}&#039;<\/code><\/pre>\n<p>If you don't use <code>awk &#039;{print $2}&#039;<\/code> the output will be <code>MD5(stdin)= ab:cd:...:ef<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The setup You want to generate Letsencrypt certificates using DNS-01 challenge (e.g. wildcard certificates) and you host your domain on Oracle Cloud. Your code is in Python and you want to use certbot-dns-oci for updating the TXT DNS records for the DNS-01 challenge. The problem You need to provide some OCI credentials to certbot-dns-oci and&hellip; <a class=\"more-link\" href=\"https:\/\/editjournal.redakt.eu\/faxmodem\/blog\/development\/cloud-serverless\/certbot-dns-oci-api-credentials-ini\/\">Continue reading <span class=\"screen-reader-text\">Creating API credentials for certbot-dns-oci<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[778],"tags":[989,862],"class_list":["post-1748","post","type-post","status-publish","format-standard","hentry","category-cloud-serverless","tag-certbot","tag-oracle-cloud-infrastructure","entry"],"_links":{"self":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1748","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/comments?post=1748"}],"version-history":[{"count":7,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1748\/revisions"}],"predecessor-version":[{"id":1755,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1748\/revisions\/1755"}],"wp:attachment":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/media?parent=1748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/categories?post=1748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/tags?post=1748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}