Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions application/single_app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ RUN set -eux; \
driver_lib="$(find /opt/microsoft/msodbcsql18/lib64 -name 'libmsodbcsql-*.so*' | sort | tail -n 1)"; \
test -n "${driver_lib}"; \
printf '[ODBC Driver 18 for SQL Server]\nDescription=Microsoft ODBC Driver 18 for SQL Server\nDriver=%s\nUsageCount=1\n' "${driver_lib}" > /etc/odbcinst.ini; \
mkdir -p /odbc-runtime/usr/lib64; \
mkdir -p /odbc-runtime/usr/lib; \
for lib in /usr/lib64/libodbc* /usr/lib/libodbc* /usr/lib64/libltdl* /usr/lib/libltdl*; do \
if [ -e "${lib}" ]; then cp -a "${lib}" /odbc-runtime/usr/lib64/; fi; \
if [ -e "${lib}" ]; then cp -a "${lib}" /odbc-runtime/usr/lib/; fi; \
done; \
find /odbc-runtime/usr/lib64 -maxdepth 1 -name 'libodbc*' | grep -q .; \
find /odbc-runtime/usr/lib64 -maxdepth 1 -name 'libltdl*' | grep -q .; \
find /odbc-runtime/usr/lib -maxdepth 1 -name 'libodbc*' | grep -q .; \
find /odbc-runtime/usr/lib -maxdepth 1 -name 'libltdl*' | grep -q .; \
tdnf clean all

RUN set -eux; \
Expand Down Expand Up @@ -129,14 +129,15 @@ RUN set -eux; \
esac; \
driver_config_dir="${driver_config_file%/odbcinst.ini}"; \
test -f "${driver_config_file}"; \
mkdir -p /odbc-runtime/usr/lib64 /odbc-runtime/opt "/odbc-runtime${driver_config_dir}" /odbc-runtime/etc; \
mkdir -p /odbc-runtime/usr/lib /odbc-runtime/opt "/odbc-runtime${driver_config_dir}" /odbc-runtime/etc; \
cp -a "${driver_config_file}" "/odbc-runtime${driver_config_dir}/"; \
if [ "${driver_config_dir}" != "/etc" ]; then cp -a "${driver_config_file}" /odbc-runtime/etc/; fi; \
cp -a /opt/microsoft /odbc-runtime/opt/; \
cp -a /usr/lib64/libodbc.so* /odbc-runtime/usr/lib64/; \
cp -a /usr/lib64/libodbcinst.so* /odbc-runtime/usr/lib64/; \
cp -a /usr/lib64/libodbccr.so* /odbc-runtime/usr/lib64/; \
cp -a /usr/lib64/libltdl.so* /odbc-runtime/usr/lib64/
for lib in /usr/lib64/libodbc.so* /usr/lib/libodbc.so* /usr/lib64/libodbcinst.so* /usr/lib/libodbcinst.so* /usr/lib64/libodbccr.so* /usr/lib/libodbccr.so* /usr/lib64/libltdl.so* /usr/lib/libltdl.so*; do \
if [ -e "${lib}" ]; then cp -a "${lib}" /odbc-runtime/usr/lib/; fi; \
done; \
find /odbc-runtime/usr/lib -maxdepth 1 -name 'libodbc*' | grep -q .; \
find /odbc-runtime/usr/lib -maxdepth 1 -name 'libltdl*' | grep -q .

WORKDIR /app

Expand All @@ -161,9 +162,11 @@ RUN set -eux; \
true|1|yes|on) \
python3 -m playwright install chromium; \
find /ms-playwright -name chrome_sandbox -exec chown root:root {} \; -exec chmod 4755 {} \;; \
mkdir -p /playwright-runtime/ms-playwright /playwright-runtime/usr/lib64 /playwright-runtime/usr/share /playwright-runtime/etc; \
mkdir -p /playwright-runtime/ms-playwright /playwright-runtime/usr/lib /playwright-runtime/usr/share /playwright-runtime/etc; \
cp -a /ms-playwright/. /playwright-runtime/ms-playwright/; \
cp -a /usr/lib64/*.so* /playwright-runtime/usr/lib64/; \
for lib in /usr/lib64/*.so* /usr/lib/*.so*; do \
if [ -e "${lib}" ]; then cp -a "${lib}" /playwright-runtime/usr/lib/; fi; \
done; \
if [ -d /usr/share/fonts ]; then cp -a /usr/share/fonts /playwright-runtime/usr/share/; fi; \
if [ -d /usr/share/fontconfig ]; then cp -a /usr/share/fontconfig /playwright-runtime/usr/share/; fi; \
if [ -d /etc/fonts ]; then cp -a /etc/fonts /playwright-runtime/etc/; fi; \
Expand Down
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.261.007"
VERSION = "0.261.009"
IS_DEVELOPMENT = is_development_env_enabled()

# Opt-out for deployments where App Service Easy Auth is active but the platform
Expand Down
3 changes: 2 additions & 1 deletion application/single_app/functions_document_access_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -2165,7 +2165,7 @@ def _query_candidate_projection_rows_for_scope(scope_key, source_scope):
'WHERE c.type = @type '
'AND c.source_scope = @source_scope '
'AND c.scope_key = @scope_key '
'AND c.access_granted = true '
'AND (c.access_granted = true OR c.approval_status = @approval_not_approved) '
'AND c.is_current_version = true '
'AND c.projection_version = @projection_version'
)
Expand All @@ -2177,6 +2177,7 @@ def _query_candidate_projection_rows_for_scope(scope_key, source_scope):
{'name': '@type', 'value': DOCUMENT_ACCESS_INDEX_TYPE},
{'name': '@source_scope', 'value': source_scope},
{'name': '@scope_key', 'value': scope_key},
{'name': '@approval_not_approved', 'value': DOCUMENT_ACCESS_APPROVAL_NOT_APPROVED},
{'name': '@projection_version', 'value': DOCUMENT_ACCESS_INDEX_SCHEMA_VERSION},
],
partition_key=scope_key,
Expand Down
54 changes: 54 additions & 0 deletions docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Distroless Runtime Overlay Path Fix

Check warning on line 1 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

Fixed in version: **0.261.009**

Related config.py version update: `application/single_app/config.py` was incremented to `0.261.009`.

## Issue Description

Container builds could fail during final-stage runtime overlay copy with:

`cannot copy to non-directory ... /usr/lib64`

The failure was first observed on:

- `COPY --from=builder /odbc-runtime/ /`

After addressing that path, the same failure surfaced on:

- `COPY --from=builder /playwright-runtime/ /`

## Root Cause Analysis

The builder staged runtime payloads under directory trees containing `usr/lib64`, then copied those trees into `/` on a distroless base image. On newer base-image layouts, `/usr/lib64` may be a symlink or other non-directory entry, and Docker BuildKit refuses to overlay a directory on top of a non-directory path.

Check warning on line 23 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

This made full-tree overlays brittle against base image filesystem changes.

## Technical Details

Files modified:

- `application/single_app/Dockerfile`
- `application/single_app/config.py`
- `functional_tests/test_sql_container_odbc_runtime.py`
- `functional_tests/test_sql_odbc_driver_18_support.py`

Code changes summary:

- Updated ODBC staging destination from `"/odbc-runtime/usr/lib64"` to `"/odbc-runtime/usr/lib"`.
- Updated Playwright staging destination from `"/playwright-runtime/usr/lib64"` to `"/playwright-runtime/usr/lib"`.
- Preserved source library glob coverage from both `/usr/lib64` and `/usr/lib` in the builder stage so either package layout remains supported.
- Kept final runtime copies (`/odbc-runtime/` and `/playwright-runtime/`) unchanged while eliminating directory-vs-non-directory path collisions at `/usr/lib64`.

## Validation

Validation evidence for the change sequence included:

- `functional_tests/test_sql_container_odbc_runtime.py` passed after assertion alignment and Dockerfile path updates.

Check warning on line 47 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
- `functional_tests/test_sql_odbc_driver_18_support.py` continued to validate SQL ODBC Driver 18 runtime/default behavior.

Check warning on line 48 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
- `functional_tests/test_deep_research_chromium_build_opt_out.py` covered Playwright Chromium build-arg and runtime copy wiring.

Check warning on line 49 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.

## Before and After

- Before: BuildKit could fail in the final stage when runtime overlay trees attempted to create `usr/lib64` as a directory over a non-directory target in the distroless base.

Check warning on line 53 in docs/explanation/fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
- After: Runtime overlays stage libraries under `usr/lib`, avoiding `/usr/lib64` target-shape conflicts while preserving SQL ODBC and Playwright native runtime packaging.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Workspace Shared File Approval Visibility Fix

Fixed in version: **0.261.009**

Related config.py version update: `application/single_app/config.py` was incremented to `0.261.009`.

## Issue Description

Files shared into personal or group workspace approval flows could fail to appear in approval-facing views even when they were waiting for approval.

The impact was that approvers could not reliably see pending files to review, which blocked the expected approve or deny workflow.

## Root Cause Analysis

The document access index scope projection candidate query filtered strictly on granted access:

- `c.access_granted = true`

Pending approval records are expected to remain ungranted until an approver acts. Those records carry a pending approval state, so the strict granted-only filter excluded them from candidate projection rows.

## Technical Details

Files modified:

- `application/single_app/functions_document_access_index.py`

Code changes summary:

- Updated `_query_candidate_projection_rows_for_scope` to include pending approval rows in addition to granted rows.
- Added the `@approval_not_approved` query parameter bound to `DOCUMENT_ACCESS_APPROVAL_NOT_APPROVED`.

Updated query predicate:

- From: `AND c.access_granted = true`
- To: `AND (c.access_granted = true OR c.approval_status = @approval_not_approved)`

This preserves existing constraints for source scope, scope key, current-version records, and projection schema version while restoring visibility for pending approval artifacts.

## Validation

Validation performed for this change set included:

- Python compile checks for changed files and `application/single_app` compile sweep.
- Security guardrails for changed Python files:
- `scripts/check_xss_sinks.py`
- `scripts/check_broken_access_control.py`

Additional branch validation:

- Updated and re-ran `functional_tests/test_sql_container_odbc_runtime.py` to align assertions with current SQL ODBC default behavior (3/3 passed).

Check warning on line 50 in docs/explanation/fixes/WORKSPACE_SHARED_FILE_APPROVAL_VISIBILITY_FIX.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.

Recommended follow-up coverage:

- Add a dedicated functional test that asserts pending approval records are included in document access index scope projections for approver-visible queues.

## Before and After

- Before: Pending approval shared files could be missing from approval visibility surfaces because only granted access rows were projected.
- After: Pending approval shared files are included in projection candidates and remain visible to approvers while still ungranted until approval.
2 changes: 2 additions & 0 deletions docs/explanation/fixes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
---

- [Chat Document Search File Name and Divider Artifact Fix](CHAT_DOCUMENT_SEARCH_FILENAME_AND_DIVIDER_FIX.md)
- [Distroless Runtime Overlay Path Fix](DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md)

Check warning on line 10 in docs/explanation/fixes/index.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
- [Workspace Shared File Approval Visibility Fix](WORKSPACE_SHARED_FILE_APPROVAL_VISIBILITY_FIX.md)
- [Semantic Kernel Startup Request Context Fix](SEMANTIC_KERNEL_STARTUP_REQUEST_CONTEXT_FIX.md)
- [Data Management Restore Route Endpoint Collision Fix](DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md)
- [Font Size and 200 Percent Zoom Fix](FONT_SIZE_AND_200_PERCENT_ZOOM_FIX.md)
Expand Down
16 changes: 16 additions & 0 deletions docs/explanation/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

For feature-focused and fix-focused drill-downs by version, see [Features by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/features) and [Fixes by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/fixes).

### **(v0.261.009)**

#### Bug Fixes

* **Shared Workspace File Approvals Are Visible To Approvers Again**
* Fixed document access index candidate selection for workspace scope projections so pending-approval records are considered alongside already granted records.
* Shared files staged for approval are intentionally not granted yet, so filtering only on `access_granted = true` could hide those files from approval experiences even though they were eligible for review.
* The projection query now includes `approval_status = not_approved` rows while still requiring current-version projection records.
* (Ref: `functions_document_access_index.py`, [Workspace Shared File Approval Visibility Fix](fixes/WORKSPACE_SHARED_FILE_APPROVAL_VISIBILITY_FIX.md))

* **Distroless Runtime Copy No Longer Fails On `/usr/lib64` Overlay Conflicts**

Check warning on line 15 in docs/explanation/release_notes.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
* Fixed Docker BuildKit failures where `COPY --from=builder /odbc-runtime/ /` or `COPY --from=builder /playwright-runtime/ /` could abort with `cannot copy to non-directory ... /usr/lib64` when the distroless base exposes `/usr/lib64` as a non-directory entry.

Check warning on line 16 in docs/explanation/release_notes.md

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains security control, sanitization, or audit marker. Recommendation%3A Confirm the change does not weaken auth, CSRF, CSP, XSS defenses, settings sanitization, redaction, audit logging, or tests.
* Updated runtime staging to copy native shared libraries into `/odbc-runtime/usr/lib` and `/playwright-runtime/usr/lib` while continuing to source candidates from both `/usr/lib64` and `/usr/lib` in the builder stage.
* This preserves SQL ODBC and Playwright Chromium runtime packaging while avoiding path-type collisions against evolving base-image filesystem layouts.
* (Ref: `Dockerfile`, `test_sql_container_odbc_runtime.py`, `test_deep_research_chromium_build_opt_out.py`, [Distroless Runtime Overlay Path Fix](fixes/DISTROLESS_RUNTIME_OVERLAY_PATH_FIX.md))

### **(v0.261.007)**

#### Bug Fixes
Expand Down
11 changes: 7 additions & 4 deletions functional_tests/test_sql_container_odbc_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def test_dockerfile_packages_odbc_runtime() -> bool:
"tdnf install -y unixODBC unixODBC-devel msodbcsql18",
"COPY --from=builder /odbc-runtime/ /",
'LD_LIBRARY_PATH="/usr/lib64:/opt/microsoft/msodbcsql18/lib64"',
"mkdir -p /odbc-runtime/usr/lib /odbc-runtime/opt",
'driver_config_path="$(odbcinst -j | while IFS= read -r line; do case "$line" in DRIVERS*) printf \'%s\\n\' "${line##*: }"; break ;; esac; done)"',
'test -n "${driver_config_path}"',
'case "${driver_config_path}" in',
Expand All @@ -39,6 +40,8 @@ def test_dockerfile_packages_odbc_runtime() -> bool:
'test -f "${driver_config_file}"',
'cp -a "${driver_config_file}" "/odbc-runtime${driver_config_dir}/"',
'if [ "${driver_config_dir}" != "/etc" ]; then cp -a "${driver_config_file}" /odbc-runtime/etc/; fi;',
'for lib in /usr/lib64/libodbc.so* /usr/lib/libodbc.so* /usr/lib64/libodbcinst.so* /usr/lib/libodbcinst.so* /usr/lib64/libodbccr.so* /usr/lib/libodbccr.so* /usr/lib64/libltdl.so* /usr/lib/libltdl.so*; do',
'if [ -e "${lib}" ]; then cp -a "${lib}" /odbc-runtime/usr/lib/; fi;',
]

missing = [snippet for snippet in expected_snippets if snippet not in dockerfile]
Expand All @@ -59,10 +62,10 @@ def test_sql_defaults_use_odbc_driver_18() -> bool:
print("🔍 Testing SQL defaults use ODBC Driver 18...")

expected_defaults = {
"application/single_app/route_backend_plugins.py": "driver or 'ODBC Driver 18 for SQL Server'",
"application/single_app/semantic_kernel_plugins/sql_query_plugin.py": "'default_driver': 'ODBC Driver 18 for SQL Server'",
"application/single_app/semantic_kernel_plugins/sql_schema_plugin.py": "'default_driver': 'ODBC Driver 18 for SQL Server'",
"application/single_app/semantic_kernel_plugins/sql_plugin_factory.py": '"driver": "ODBC Driver 18 for SQL Server"',
"application/single_app/route_backend_plugins.py": "driver=driver or DEFAULT_SQL_SERVER_ODBC_DRIVER",
"application/single_app/semantic_kernel_plugins/sql_query_plugin.py": "'default_driver': DEFAULT_SQL_SERVER_ODBC_DRIVER",
"application/single_app/semantic_kernel_plugins/sql_schema_plugin.py": "'default_driver': DEFAULT_SQL_SERVER_ODBC_DRIVER",
"application/single_app/semantic_kernel_plugins/sql_plugin_factory.py": '"driver": DEFAULT_SQL_SERVER_ODBC_DRIVER',
"application/single_app/static/js/plugin_modal_stepper.js": "additionalFields.driver || 'ODBC Driver 18 for SQL Server'",
"application/single_app/semantic_kernel_plugins/SQL_Plugins_Configuration_Guide.md": 'DRIVER={ODBC Driver 18 for SQL Server}',
}
Expand Down
2 changes: 1 addition & 1 deletion functional_tests/test_sql_odbc_driver_18_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_dockerfile_installs_driver_18_runtime():
assert "find /opt/microsoft/msodbcsql18/lib64 -name 'libmsodbcsql-*.so*'" in dockerfile, \
'Docker build should resolve the installed Driver 18 shared library path'
assert "UsageCount=1" in dockerfile, 'Docker build should create a deterministic odbcinst.ini registration'
assert '/odbc-runtime/usr/lib64' in dockerfile, \
assert '/odbc-runtime/usr/lib' in dockerfile, \
'Docker build should stage unixODBC libraries from Azure Linux library paths before runtime copy'
assert "/usr/lib64/libodbc* /usr/lib/libodbc*" in dockerfile, \
'Docker build should support unixODBC libraries installed under /usr/lib64 or /usr/lib'
Expand Down
Loading