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
3 changes: 3 additions & 0 deletions .env.demo
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ HOSTNAME='localhost'
# To add more clients, simply add comma separated values of client names
SUPPORTED_SSO_CLIENTS=CREDEBL

# Key for agent base wallet
AGENT_API_KEY='supersecret-that-too-16chars'

# To add more client add the following variables for each additional client.
# Replace the `CLIENT-NAME` with the appropriate client name as added in `SUPPORTED_SSO_CLIENTS`
# Default client will not need the following details
Expand Down
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ HOSTNAME='localhost' # Hostname or unique identifier
# To add more clients, simply add comma separated values of client names
SUPPORTED_SSO_CLIENTS=CREDEBL

# Key for agent base wallet
AGENT_API_KEY='supersecret-that-too-16chars'

# To add more client add the following variables for each additional client.
# Replace the `CLIENT-NAME` with the appropriate client name as added in `SUPPORTED_SSO_CLIENTS`
# Default client will not need the following details
Expand Down
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,4 @@ module.exports = {
'prefer-template': 'error',
quotes: ['warn', 'single', { allowTemplateLiterals: true }]
}
};
};
3 changes: 3 additions & 0 deletions .github/dco.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
allowRemediationCommits:
individual: true
thirdParty: true
9 changes: 8 additions & 1 deletion .github/workflows/continuous-delivery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ jobs:
id: get_tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
Expand All @@ -57,6 +63,7 @@ jobs:
context: .
file: Dockerfiles/Dockerfile.${{ matrix.service }}
push: true
platforms: linux/amd64,linux/arm64
tags: |
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.service }}:${{ env.TAG }}
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.service }}:latest
${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ matrix.service }}:latest
9 changes: 5 additions & 4 deletions apps/agent-provisioning/AFJ/scripts/start_agent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ AFJ_VERSION=${14}
INDY_LEDGER=${15}
INBOUND_ENDPOINT=${16}
SCHEMA_FILE_SERVER_URL=${17}

AGENT_API_KEY="${18}"
ADMIN_PORT_FILE="$PWD/apps/agent-provisioning/AFJ/port-file/last-admin-port.txt"
INBOUND_PORT_FILE="$PWD/apps/agent-provisioning/AFJ/port-file/last-inbound-port.txt"
ADMIN_PORT=8001
Expand Down Expand Up @@ -122,7 +122,7 @@ if [ -f "$CONFIG_FILE" ]; then
rm "$CONFIG_FILE"
fi

cat <<EOF >${CONFIG_FILE}
cat <<EOF >"$CONFIG_FILE"
{
"label": "${AGENCY}_${CONTAINER_NAME}",
"walletId": "$WALLET_NAME",
Expand Down Expand Up @@ -154,7 +154,8 @@ cat <<EOF >${CONFIG_FILE}
"webhookUrl": "$WEBHOOK_HOST/wh/$AGENCY",
"adminPort": $ADMIN_PORT,
"tenancy": $TENANT,
"schemaFileServerURL": "$SCHEMA_FILE_SERVER_URL"
"schemaFileServerURL": "$SCHEMA_FILE_SERVER_URL",
"apiKey": "$AGENT_API_KEY"
}
EOF

Expand Down Expand Up @@ -238,7 +239,7 @@ if [ $? -eq 0 ]; then
container_logs=$(docker logs $(docker ps -q --filter "name=${AGENCY}_${CONTAINER_NAME}"))

# Extract the token from the logs using sed
token=$(echo "$container_logs" | sed -nE 's/.*API Token: ([^ ]+).*/\1/p')
token=$(echo "$container_logs" | sed -nE 's/.*** API Key: ([^ ]+).*/\1/p')

# Print the extracted token
echo "Token: $token"
Expand Down
75 changes: 72 additions & 3 deletions apps/agent-provisioning/AFJ/scripts/start_agent_ecs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ random_string=$(generate_random_string)
# Print the generated random string
echo "Random String: $random_string"

SERVICE_NAME="${AGENCY}-${CONTAINER_NAME}-service-${random_string}"
SERVICE_NAME="${CONTAINER_NAME}-service-test"
EXTERNAL_IP=$(echo "$2" | tr -d '[:space:]')
ADMIN_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-admin-port.txt"
INBOUND_PORT_FILE="$PWD/agent-provisioning/AFJ/port-file/last-inbound-port.txt"
Expand Down Expand Up @@ -153,7 +153,7 @@ CONTAINER_DEFINITIONS=$(
[
{
"name": "$CONTAINER_NAME",
"image": "${AFJ_IMAGE_URL}",
"image": "${AFJ_VERSION}",
"cpu": 154,
"memory": 307,
"portMappings": [
Expand Down Expand Up @@ -194,6 +194,14 @@ CONTAINER_DEFINITIONS=$(
}
],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/$TESKDEFINITION_FAMILY",
"awslogs-create-group": "true",
"awslogs-region": "ap-south-1",
"awslogs-stream-prefix": "ecs"
},
"ulimits": []
}
]
Expand Down Expand Up @@ -262,6 +270,67 @@ if [ $? -eq 0 ]; then
sleep 10
fi
done
# Describe the ECS service and filter by service name
service_description=$(aws ecs describe-services --service $SERVICE_NAME --cluster $CLUSTER_NAME --region $AWS_PUBLIC_REGION)
echo "service_description=$service_description"


# Extract Task ID from the service description events
task_id=$(echo "$service_description" | jq -r '.services[0].events[] | select(.message | test("has started 1 tasks")) | .message | capture("\\(task (?<id>[^)]+)\\)") | .id')
#echo "task_id=$task_id"

# to fetch log group of container
.............................................................
log_group=/ecs/$TESKDEFINITION_FAMILY
echo "log_group=$log_group"

# Get Log Stream Name
log_stream=ecs/$CONTAINER_NAME/$task_id

echo "logstrem=$log_stream"


# Fetch logs
#echo "$(aws logs get-log-events --log-group-name "/ecs/$TESKDEFINITION_FAMILY/$CONTAINER_NAME" --log-stream-name "$log_stream" --region $AWS_PUBLIC_REGION)"

# Check if the token folder exists, and create it if it doesn't
token_folder="$PWD/agent-provisioning/AFJ/token"
if [ ! -d "$token_folder" ]; then
mkdir -p "$token_folder"
fi

# Set maximum retry attempts
RETRIES=3

# Loop to attempt retrieving token from logs
# Loop to attempt retrieving token from logs
for attempt in $(seq 1 $RETRIES); do
echo "Attempt $attempt: Checking service logs for token..."

# Fetch logs and grep for API token
token=$(aws logs get-log-events \
--log-group-name "$log_group" \
--log-stream-name "$log_stream" \
--region ap-southeast-1 \
| grep -o '*** API Key: [^ ]*' \
| cut -d ' ' -f 3
)
# echo "token=$token"
if [ -n "$token" ]; then
echo "Token found: $token"
# Write token to a file
echo "{\"token\": \"$token\"}" > "$PWD/agent-provisioning/AFJ/token/${AGENCY}_${CONTAINER_NAME}.json"
break # Exit loop if token is found
else
echo "Token not found in logs. Retrying..."
if [ $attempt -eq $RETRIES ]; then
echo "Reached maximum retry attempts. Token not found."
fi
fi
# Add a delay of 10 seconds between retries
sleep 10
done


echo "Creating agent config"
cat <<EOF >${PWD}/agent-provisioning/AFJ/endpoints/${AGENCY}_${CONTAINER_NAME}.json
Expand All @@ -273,7 +342,7 @@ EOF

cat <<EOF >${PWD}/agent-provisioning/AFJ/token/${AGENCY}_${CONTAINER_NAME}.json
{
"token" : ""
"token" : "$token"
}
EOF

Expand Down
32 changes: 23 additions & 9 deletions apps/agent-provisioning/src/agent-provisioning.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,39 @@

@Injectable()
export class AgentProvisioningService {

constructor(
private readonly logger: Logger
) { }
constructor(private readonly logger: Logger) {}

/**
* Description: Wallet provision
* @param payload
* @param payload
* @returns Get DID and verkey
*/
async walletProvision(payload: IWalletProvision): Promise<object> {
try {

const { containerName, externalIp, orgId, seed, walletName, walletPassword, walletStorageHost, walletStoragePassword, walletStoragePort, walletStorageUser, webhookEndpoint, agentType, protocol, credoImage, tenant, indyLedger, inboundEndpoint } = payload;
const {
containerName,
externalIp,
orgId,
seed,
walletName,
walletPassword,
walletStorageHost,
walletStoragePassword,
walletStoragePort,
walletStorageUser,

Check warning

Code scanning / CodeQL

Shell command built from environment values Medium

This shell command depends on an uncontrolled
absolute path
.

Copilot Autofix

AI 6 months ago

To fix the problem, we should avoid constructing a shell command as a single string and passing it to exec. Instead, we should use execFile (or execFileSync if synchronous execution is desired), which allows us to specify the command and its arguments separately. This prevents shell interpretation of arguments and mitigates the risk of shell injection.

Detailed steps:

  • Parse the shell script path and arguments separately.
  • Use execFile to run the shell script, passing the arguments as an array.
  • Ensure that all arguments are passed as individual array elements, not concatenated into a single string.
  • Update the code in apps/agent-provisioning/src/agent-provisioning.service.ts at lines 43–45 to use execFile instead of exec.
  • No additional dependencies are required, as execFile is part of Node.js's child_process module.

Suggested changeset 1
apps/agent-provisioning/src/agent-provisioning.service.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/apps/agent-provisioning/src/agent-provisioning.service.ts b/apps/agent-provisioning/src/agent-provisioning.service.ts
--- a/apps/agent-provisioning/src/agent-provisioning.service.ts
+++ b/apps/agent-provisioning/src/agent-provisioning.service.ts
@@ -42,5 +42,30 @@
         // The wallet provision command is used to invoke a shell script
-        const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${process.env.SCHEMA_FILE_SERVER_URL} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`;
+        const scriptPath = process.cwd() + process.env.AFJ_AGENT_SPIN_UP;
+        const walletProvisionArgs = [
+          orgId,
+          externalIp,
+          walletName,
+          walletPassword,
+          seed,
+          webhookEndpoint,
+          walletStorageHost,
+          walletStoragePort,
+          walletStorageUser,
+          walletStoragePassword,
+          containerName,
+          protocol,
+          tenant,
+          credoImage,
+          indyLedger,
+          inboundEndpoint,
+          process.env.SCHEMA_FILE_SERVER_URL,
+          apiKey,
+          process.env.AGENT_HOST,
+          process.env.AWS_ACCOUNT_ID,
+          process.env.S3_BUCKET_ARN,
+          process.env.CLUSTER_NAME,
+          process.env.TESKDEFINITION_FAMILY
+        ];
         const spinUpResponse: object = new Promise(async (resolve) => {
-          await exec(walletProvision, async (err, stdout, stderr) => {
+          await execFile(scriptPath, walletProvisionArgs, async (err, stdout, stderr) => {
             this.logger.log(`shell script output: ${stdout}`);
EOF
@@ -42,5 +42,30 @@
// The wallet provision command is used to invoke a shell script
const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${process.env.SCHEMA_FILE_SERVER_URL} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`;
const scriptPath = process.cwd() + process.env.AFJ_AGENT_SPIN_UP;
const walletProvisionArgs = [
orgId,
externalIp,
walletName,
walletPassword,
seed,
webhookEndpoint,
walletStorageHost,
walletStoragePort,
walletStorageUser,
walletStoragePassword,
containerName,
protocol,
tenant,
credoImage,
indyLedger,
inboundEndpoint,
process.env.SCHEMA_FILE_SERVER_URL,
apiKey,
process.env.AGENT_HOST,
process.env.AWS_ACCOUNT_ID,
process.env.S3_BUCKET_ARN,
process.env.CLUSTER_NAME,
process.env.TESKDEFINITION_FAMILY
];
const spinUpResponse: object = new Promise(async (resolve) => {
await exec(walletProvision, async (err, stdout, stderr) => {
await execFile(scriptPath, walletProvisionArgs, async (err, stdout, stderr) => {
this.logger.log(`shell script output: ${stdout}`);
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
webhookEndpoint,
agentType,
protocol,
credoImage,
tenant,
indyLedger,
inboundEndpoint,
apiKey
} = payload;
if (agentType === AgentType.AFJ) {
// The wallet provision command is used to invoke a shell script
const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${process.env.SCHEMA_FILE_SERVER_URL} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`;
const walletProvision = `${process.cwd() + process.env.AFJ_AGENT_SPIN_UP} ${orgId} "${externalIp}" "${walletName}" "${walletPassword}" ${seed} ${webhookEndpoint} ${walletStorageHost} ${walletStoragePort} ${walletStorageUser} ${walletStoragePassword} ${containerName} ${protocol} ${tenant} ${credoImage} "${indyLedger}" ${inboundEndpoint} ${process.env.SCHEMA_FILE_SERVER_URL} ${apiKey} ${process.env.AGENT_HOST} ${process.env.AWS_ACCOUNT_ID} ${process.env.S3_BUCKET_ARN} ${process.env.CLUSTER_NAME} ${process.env.TESKDEFINITION_FAMILY}`;
const spinUpResponse: object = new Promise(async (resolve) => {

await exec(walletProvision, async (err, stdout, stderr) => {
this.logger.log(`shell script output: ${stdout}`);
if (stderr) {
Expand Down
Loading