# Upload SSL certs via axapi v3.0

**URL:** <https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579>\
**Category:** ADC - Application Delivery\
**Tags:** axapi\
**Created:** [December 10, 2019, 10:20pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579 "2019-12-10T22:20:20Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![agomez](https://avatars.discourse-cdn.com/v4/letter/a/d07c76/32.png) [@agomez](https://community.a10networks.com/u/agomez)\
**Post date:** [December 10, 2019, 10:20pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/1 "2019-12-10T22:20:20Z")

</div>

I have tried using the file/ssl-cert AXAPI 3.0 endpoint to upload an SSL cert, and have so far been unable to with either curl or Ansible.

```yaml
curl -k -X POST -v \
  https://a10.example./axapi/v3/file/ssl-cert \
  -H "Authorization: A10 ${SIG}" \
  -H 'content-type: application/json' \
  -d '{
"ssl-cert": {
  "file": "example.com.crt",
  "certificate-type":"pem",
  "file-handle": "example.com.crt",
  "action": "import"
  }
}'

```

The response:

```yaml
{ 
"response": {
  "status": "fail",
  "err": {
  "code": 1023590403,
  "from": "JSON",
  "msg": "Failed to handle field \"file-handle\". Incorrect file value.",
  "location": "ssl-cert.file-handle"
  }
  }

```

I see how this would fail, how could curl possibly know to upload this file handle, more so how would the API know to pull that file sitting on my local machine?  
Is it not possible to upload an SSL cert via AXAPI? I see remote-file is an option but this does not work for us in our environment.

---

<div class="post-metadata">

**Author:** ![mdunn](https://avatars.discourse-cdn.com/v4/letter/m/87869e/32.png) [@mdunn](https://community.a10networks.com/u/mdunn)\
**Post date:** [September 30, 2021, 3:35pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/2 "2021-09-30T15:35:16Z")

</div>

I had a customer exploring this, and ultimately we came up with the following. The cert and key are pushed in two separate calls:

**SSL Cert Push**

```yaml
curl -vvv -k -H "Authorization: A10 `./APIauthv3.sh 10.22.10.54`" -F "json=@filessl.json;type=application/json"  -F "file=@local_cert.pem;type=application/octet-stream" https://10.22.10.54/axapi/v3/file/ssl-cert

```

**SSL Key Push**

```yaml
curl -vvv -k -H "Authorization: A10 `./APIauthv3.sh 10.22.10.54`" -F "json=@filessl_key.json;type=application/json"  -F "file=@local_key.pem;type=application/octet-stream" https://10.22.10.54/axapi/v3/file/ssl-key

```

Attached is the Auth script as well as the filessl and filessl\_key json files. The expected response is a HTTP/204.

[axapi-files.zip](https://community.a10networks.com/uploads/short-url/8fbvTdSua983Ddyw2tC8FbfGLue.zip) (676 Bytes)

---

<div class="post-metadata">

**Author:** ![tacke](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tacke](https://community.a10networks.com/u/tacke)\
**Post date:** [August 22, 2023, 12:37pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/3 "2023-08-22T12:37:46Z")

</div>

Hi!  
This looks much like what I would like to accomplish. Thanks for the zip file with the helpful ideas.  
Here’s, what’s happening for me:

```yaml
    - endpoint: /axapi/v3/file/ssl-cert
      http_method: POST
      request_body:
        file_name: test-hades-db-cert-2023
        ssl-cert:
          action: import
          file: test-hades-db-cert-2023
          file-handle: hades-db.gsi.de.pem
      response_body:
        response:
          err:
            code: 1023524874
            from: JSON
            location: ssl-cert.action
            msg: Failed to handle json field "action". JSON field cannot be handled. It might be undefined or disabled by other fields.
          status: fail
      status_code: 400

```

If I remove the `action` field I get nearly the same error, just for `file-handle`. If I remove that, I get this:

```yaml
      response_body:
        response:
          err:
            code: 1023459337
            from: BACKEND
            msg: Backend Error
          status: fail
      status_code: 400

```

How is this supposed to work?  
(This is on ACOS 4.1.4, if that’s important?)

---

<div class="post-metadata">

**Author:** ![mdunn](https://avatars.discourse-cdn.com/v4/letter/m/87869e/32.png) [@mdunn](https://community.a10networks.com/u/mdunn)\
**Post date:** [August 29, 2023, 3:11am UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/4 "2023-08-29T03:11:27Z")

</div>

How are you performing the HTTP Request? I successfully tested this with CURL, but I have not extended the testing to other tools.

---

<div class="post-metadata">

**Author:** ![tacke](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tacke](https://community.a10networks.com/u/tacke)\
**Post date:** [August 30, 2023, 8:38am UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/5 "2023-08-30T08:38:20Z")

</div>

I am using ansible with the official ansible collection from a10 [https://galaxy.ansible.com/a10/acos\_axapi](https://galaxy.ansible.com/a10/acos_axapi).  
A kind engineer from A10 helped us analyze this in more detail and we finally we found, that the respective module needs `file` and `file_handle` being the same.  
This looks like this then:

```yaml
    - name: "Configure SSL Certificate"
      a10.acos_axapi.a10_file_ssl_cert:
        state: present
        action: import
        certificate_type: pem
        file:        "test-cert-2023"
        file_handle: "test-cert-2023"
        file_path: "/tmp/netlb-certs/sometest.pem"

```

`file_handle` usually should be the name of the uploaded (source) file. But the ansible module sets the source file name in the POST to be the value of the `file` attribute [here](https://github.com/a10networks/a10-acos-axapi/blob/c238602ac7a02d066522a448574ba986e2c21e4e/plugins/modules/a10_file_ssl_cert.py#L284).

---

<div class="post-metadata">

**Author:** ![lavi](https://avatars.discourse-cdn.com/v4/letter/l/7ab992/32.png) [@lavi](https://community.a10networks.com/u/lavi)\
**Post date:** [March 31, 2025, 3:08pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/6 "2025-03-31T15:08:25Z")

</div>

Did you managed to upload the cert file using CURL? can you share the command you used?

---

<div class="post-metadata">

**Author:** ![mdunn](https://avatars.discourse-cdn.com/v4/letter/m/87869e/32.png) [@mdunn](https://community.a10networks.com/u/mdunn)\
**Post date:** [March 31, 2025, 3:52pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/7 "2025-03-31T15:52:21Z")

</div>

Can you try these CURL commands?

**SSL Cert Push**  
`curl -vvv -k -H "Authorization: A10 ./APIauthv3.sh 10.22.10.54" -F "json=@filessl.json;type=application/json" -F "file=@local_cert.pem;type=application/octet-stream" https://10.22.10.54/axapi/v3/file/ssl-cert`

**SSL Key Push**  
`curl -vvv -k -H "Authorization: A10 ./APIauthv3.sh 10.22.10.54" -F "json=@filessl_key.json;type=application/json" -F "file=@local_key.pem;type=application/octet-stream" https://10.22.10.54/axapi/v3/file/ssl-key`

The APIauth script is posted above in the answers section as well.

---

<div class="post-metadata">

**Author:** ![lavi](https://avatars.discourse-cdn.com/v4/letter/l/7ab992/32.png) [@lavi](https://community.a10networks.com/u/lavi)\
**Post date:** [April 1, 2025, 8:49am UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/8 "2025-04-01T08:49:02Z")

</div>

Thanks for the fast reply, but the axapi-file.zip file is not reachable… so I can’t tell what is:

filessl\_key.json

No issue for APIauthv3.sh script, as this just get a TOKEN from A10, which I know how to get it.

---

<div class="post-metadata">

**Author:** ![john\_allen](https://avatars.discourse-cdn.com/v4/letter/j/e19adc/32.png) [@john\_allen](https://community.a10networks.com/u/john_allen)\
**Post date:** [April 1, 2025, 5:22pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/9 "2025-04-01T17:22:47Z")

</div>

@filessl.json contains something like this:

{ “ssl-cert”: { “certificate-type”: “pem”, “file”: “cert1”, “file-handle”: “lab1.pem”, “action”: “import” }}

Or you can just add the JSON directly as long as the quotes are properly escaped.

@filessl\_key.json contains something like this:

{ “ssl-key”: { “file”: “cert1-key”, “file-handle”: “lab1-key.pem”, “action”: “import” }}

‘file’ will be the name on the Thunder node, ‘file-handle’ is the name of the local file defined in the second part of the call.

---

<div class="post-metadata">

**Author:** ![lavi](https://avatars.discourse-cdn.com/v4/letter/l/7ab992/32.png) [@lavi](https://community.a10networks.com/u/lavi)\
**Post date:** [April 2, 2025, 11:52am UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/10 "2025-04-02T11:52:17Z")

</div>

Thanks it is working now.

Just one note, file-handle value on json file should be the file name only without the full path.

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![john\_allen](https://avatars.discourse-cdn.com/v4/letter/j/e19adc/32.png) [@john\_allen](https://community.a10networks.com/u/john_allen)\
**Post date:** [April 2, 2025, 2:37pm UTC](https://community.a10networks.com/t/upload-ssl-certs-via-axapi-v3-0/579/11 "2025-04-02T14:37:50Z")

</div>

Yes, thank you for clarifying 🙂 These are multi-part HTTP calls: first part is the JSON struct, and the second part is the actual file contents.
