Skip to content

feat(ldapsearch):add custom PKI/internal CA support in TLS connections#1954

Open
CharlesLR-sekoia wants to merge 3 commits intodevelopfrom
feat/ldapsearch/support_pki
Open

feat(ldapsearch):add custom PKI/internal CA support in TLS connections#1954
CharlesLR-sekoia wants to merge 3 commits intodevelopfrom
feat/ldapsearch/support_pki

Conversation

@CharlesLR-sekoia
Copy link
Contributor

@CharlesLR-sekoia CharlesLR-sekoia commented Jan 23, 2026

Summary by Sourcery

Add configurable TLS client behavior for Microsoft Active Directory connections, including support for an optional custom CA certificate and corresponding configuration schema updates.

New Features:

  • Introduce an optional ca_certificate configuration field to provide a PEM-encoded CA certificate for TLS verification in Microsoft Active Directory connections.

Enhancements:

  • Update the Microsoft Active Directory TLS client to use certificate validation with a temporary CA file when a custom CA certificate is provided, and to disable certificate validation when it is not.
  • Configure the LDAP server connection to use SSL on port 636 with the appropriate TLS settings derived from the module configuration.

Documentation:

  • Document the new ca_certificate configuration option in the changelog with a new 1.5.0 release entry.

Tests:

  • Add tests covering TLS configuration behavior with and without a custom CA certificate, including use of SSL port 636 and credential handling in the LDAP connection.

Chores:

  • Bump the Microsoft Active Directory integration version from 1.4.3 to 1.5.0 in the manifest.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 23, 2026

Reviewer's Guide

Implements TLS client configuration for Microsoft Active Directory actions with optional custom CA support, adds configuration/plumbing for the new ca_certificate option, and covers the behavior with new tests and documentation updates.

Sequence diagram for TLS client creation with optional custom CA certificate

sequenceDiagram
    participant Caller
    participant MicrosoftADAction
    participant MicrosoftADModule
    participant MicrosoftADConfiguration
    participant Tempfile
    participant Tls
    participant Server
    participant Connection

    Caller->>MicrosoftADAction: access client
    MicrosoftADAction->>MicrosoftADModule: get configuration
    MicrosoftADModule->>MicrosoftADConfiguration: return configuration
    MicrosoftADAction->>MicrosoftADConfiguration: read ca_certificate
    alt ca_certificate is present
        MicrosoftADAction->>Tempfile: create pem file and write ca_certificate
        Tempfile-->>MicrosoftADAction: return ca_file path
        MicrosoftADAction->>Tls: create validate CERT_REQUIRED, ca_certs_file ca_file
    else ca_certificate is absent
        MicrosoftADAction->>Tls: create validate CERT_NONE
    end
    MicrosoftADAction->>Server: create host, port 636, use_ssl true, tls tls_config
    MicrosoftADAction->>Connection: create with server, credentials, auto_bind
    Connection-->>MicrosoftADAction: return bound connection
    MicrosoftADAction-->>Caller: return client (connection)
Loading

Class diagram for updated Microsoft Active Directory configuration and action TLS setup

classDiagram
    class MicrosoftADConfiguration {
        +str servername
        +str admin_username
        +str admin_password
        +str ca_certificate
    }

    class MicrosoftADModule {
        +MicrosoftADConfiguration configuration
    }

    class MicrosoftADAction {
        +MicrosoftADModule module
        +client
    }

    class Tls {
        +int validate
        +str ca_certs_file
    }

    class Server {
        +str host
        +int port
        +bool use_ssl
        +Tls tls
    }

    class Connection {
        +Server server
        +str user
        +str password
        +bool auto_bind
    }

    MicrosoftADModule --> MicrosoftADConfiguration : has
    MicrosoftADAction --> MicrosoftADModule : uses
    MicrosoftADAction --> Connection : creates
    Connection --> Server : uses
    Server --> Tls : uses
    MicrosoftADAction --> Tls : configures
Loading

File-Level Changes

Change Details Files
Add TLS client configuration that conditionally uses a provided CA certificate for server verification or disables certificate verification when none is provided.
  • Introduce logic in the MicrosoftADAction.client cached_property to read an optional PEM CA certificate from configuration.
  • When a CA certificate is present, write it to a temporary .pem file and construct a Tls object with CERT_REQUIRED and ca_certs_file pointing to that file.
  • When no CA certificate is present, construct a Tls object with CERT_NONE to disable certificate validation.
  • Pass the constructed Tls configuration into the Server initialization while keeping SSL on port 636 and existing connection behavior.
MicrosoftActiveDirectory/microsoft_ad/actions_base.py
Extend configuration, manifest, and documentation to support the optional ca_certificate parameter.
  • Add ca_certificate field to MicrosoftADConfiguration as an optional PEM-encoded CA certificate string.
  • Expose ca_certificate in manifest.json configuration schema with an appropriate description, and bump the integration version from 1.4.3 to 1.5.0.
  • Document the new ca_certificate option in CHANGELOG with a 1.5.0 release entry describing internal PKI/custom CA support.
MicrosoftActiveDirectory/microsoft_ad/models/common_models.py
MicrosoftActiveDirectory/manifest.json
MicrosoftActiveDirectory/CHANGELOG.md
Add tests covering TLS client configuration behavior with and without a CA certificate, server setup, and connection credentials.
  • Introduce TestClientTlsConfiguration test class that patches Tls, Server, and Connection to validate client behavior.
  • Add tests to ensure CERT_NONE is used when no CA certificate is provided and CERT_REQUIRED with a temporary CA file is used when a certificate is present.
  • Add a test verifying that the CA certificate content is written correctly to the temporary file used by Tls.
  • Add tests ensuring the Server is configured with SSL on port 636 and that Connection is created with the configured admin credentials.
MicrosoftActiveDirectory/tests/test_base.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The client property writes the CA certificate to a named temporary file with delete=False but never cleans it up, which can leak files over time; consider using a context-specific cleanup strategy (e.g., tracking and deleting on process shutdown) or an in-memory mechanism if the TLS library supports it.
  • When deciding whether to enable CERT_REQUIRED, you currently check only for a truthy ca_certificate string; you may want to guard against empty/whitespace-only values or clearly validate that the content looks like a PEM certificate before writing and using it.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `client` property writes the CA certificate to a named temporary file with `delete=False` but never cleans it up, which can leak files over time; consider using a context-specific cleanup strategy (e.g., tracking and deleting on process shutdown) or an in-memory mechanism if the TLS library supports it.
- When deciding whether to enable `CERT_REQUIRED`, you currently check only for a truthy `ca_certificate` string; you may want to guard against empty/whitespace-only values or clearly validate that the content looks like a PEM certificate before writing and using it.

## Individual Comments

### Comment 1
<location> `MicrosoftActiveDirectory/microsoft_ad/actions_base.py:20-24` </location>
<code_context>
     def client(self):
+        tls_config = None
+        ca_cert = self.module.configuration.ca_certificate
+        if ca_cert:
+            with tempfile.NamedTemporaryFile(mode="w", suffix=".pem", delete=False) as f:
+                f.write(ca_cert)
+                ca_file = f.name
+            tls_config = Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=ca_file)
+        else:
+            tls_config = Tls(validate=ssl.CERT_NONE)
</code_context>

<issue_to_address>
**🚨 issue (security):** Temporary CA cert file is never cleaned up, which can lead to file-system clutter and potential leakage of sensitive material.

Because `NamedTemporaryFile(..., delete=False)` is used, these PEM files will remain on disk indefinitely, causing clutter and potentially exposing CA material. Please either rely on `delete=True` (if `ldap3` can use the open file handle) or explicitly remove the temp file once the LDAP connection is established (e.g., with a `try/finally` around connection creation or a helper that manages the file lifecycle).
</issue_to_address>

### Comment 2
<location> `MicrosoftActiveDirectory/microsoft_ad/actions_base.py:25-26` </location>
<code_context>
+                f.write(ca_cert)
+                ca_file = f.name
+            tls_config = Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=ca_file)
+        else:
+            tls_config = Tls(validate=ssl.CERT_NONE)
+
         server = Server(
</code_context>

<issue_to_address>
**🚨 issue (security):** Falling back to `CERT_NONE` fully disables TLS verification, which is a notable security regression compared to typical defaults.

When `ca_certificate` is not provided, this path now unconditionally sets `validate=ssl.CERT_NONE`, disabling certificate verification. Prefer either relying on the library’s default trust store by omitting `tls_config` in the `else` branch, or introducing an explicit option (e.g. `skip_tls_verification`) so that turning off verification is an intentional, opt‑in choice rather than the default behavior.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for custom PKI/internal CA certificates in TLS connections for the Microsoft Active Directory integration. It allows users to optionally provide a custom CA certificate for environments using internal certificate authorities while maintaining backward compatibility.

Changes:

  • Added an optional ca_certificate configuration parameter to support custom CA certificates for TLS verification
  • Updated TLS client implementation to write CA certificates to temporary files and configure certificate validation accordingly
  • Added comprehensive test coverage for TLS configuration scenarios including custom CA certificates and SSL/port configuration

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
manifest.json Added ca_certificate field to configuration schema and bumped version to 1.5.0
microsoft_ad/models/common_models.py Added optional ca_certificate field to MicrosoftADConfiguration model
microsoft_ad/actions_base.py Implemented TLS configuration with custom CA support, writing certificates to temporary files
tests/test_base.py Added comprehensive test suite for TLS configuration covering multiple scenarios
CHANGELOG.md Documented the new feature in version 1.5.0 release notes

@CharlesLR-sekoia CharlesLR-sekoia changed the title add custom PKI/internal CA support in TLS connections feat(ldapsearch):add custom PKI/internal CA support in TLS connections Jan 30, 2026
Copy link
Contributor

@mchupeau-sk mchupeau-sk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for me, you can merge if it's finish

@mchupeau-sk
Copy link
Contributor

@CharlesLR-sekoia there is just a conflict for the version

@CharlesLR-sekoia
Copy link
Contributor Author

thanks @mchupeau-sk not yes tested in production environment asprivate app. I will come back to you ASAP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants